#include <vlib/threads.h>
-#include <vlib/stat_weak_inlines.h>
+#include <vlib/stats/stats.h>
u32
vl (void *p)
vlib_thread_main_t *tm = &vlib_thread_main;
vlib_worker_thread_t *w;
vlib_thread_registration_t *tr;
+ cpu_set_t cpuset;
u32 n_vlib_mains = 1;
u32 first_index = 1;
u32 i;
uword *avail_cpu;
+ u32 stats_num_worker_threads_dir_index;
+
+ stats_num_worker_threads_dir_index =
+ vlib_stats_add_gauge ("/sys/num_worker_threads");
+ ASSERT (stats_num_worker_threads_dir_index != ~0);
/* get bitmaps of active cpu cores and sockets */
tm->cpu_core_bitmap =
tm->cpu_socket_bitmap = clib_bitmap_set (0, 0, 1);
/* pin main thread to main_lcore */
- if (tm->cb.vlib_thread_set_lcore_cb)
- {
- tm->cb.vlib_thread_set_lcore_cb (0, tm->main_lcore);
- }
- else
- {
- cpu_set_t cpuset;
- CPU_ZERO (&cpuset);
- CPU_SET (tm->main_lcore, &cpuset);
- pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
- }
+ CPU_ZERO (&cpuset);
+ CPU_SET (tm->main_lcore, &cpuset);
+ pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
/* Set up thread 0 */
vec_validate_aligned (vlib_worker_threads, 0, CLIB_CACHE_LINE_BYTES);
clib_bitmap_free (avail_cpu);
tm->n_vlib_mains = n_vlib_mains;
+ vlib_stats_set_gauge (stats_num_worker_threads_dir_index, n_vlib_mains - 1);
/*
* Allocate the remaining worker threads, and thread stack vector slots
fq = clib_mem_alloc_aligned (sizeof (*fq), CLIB_CACHE_LINE_BYTES);
clib_memset (fq, 0, sizeof (*fq));
fq->nelts = nelts;
- fq->vector_threshold = 128; // packets
+ fq->vector_threshold = 2 * VLIB_FRAME_SIZE;
vec_validate_aligned (fq->elts, nelts - 1, CLIB_CACHE_LINE_BYTES);
- if (1)
+ if (nelts & (nelts - 1))
{
- if (((uword) & fq->tail) & (CLIB_CACHE_LINE_BYTES - 1))
- fformat (stderr, "WARNING: fq->tail unaligned\n");
- if (((uword) & fq->head) & (CLIB_CACHE_LINE_BYTES - 1))
- fformat (stderr, "WARNING: fq->head unaligned\n");
- if (((uword) fq->elts) & (CLIB_CACHE_LINE_BYTES - 1))
- fformat (stderr, "WARNING: fq->elts unaligned\n");
-
- if (sizeof (fq->elts[0]) % CLIB_CACHE_LINE_BYTES)
- fformat (stderr, "WARNING: fq->elts[0] size %d\n",
- sizeof (fq->elts[0]));
- if (nelts & (nelts - 1))
- {
- fformat (stderr, "FATAL: nelts MUST be a power of 2\n");
- abort ();
- }
+ fformat (stderr, "FATAL: nelts MUST be a power of 2\n");
+ abort ();
}
return (fq);
{
void *rv;
vlib_worker_thread_t *w = arg;
+ vlib_main_t *vm = 0;
w->lwp = syscall (SYS_gettid);
w->thread_id = pthread_self ();
__os_thread_index = w - vlib_worker_threads;
- vlib_process_start_switch_stack (vlib_get_main_by_index (__os_thread_index),
- 0);
+ vm = vlib_global_main.vlib_mains[__os_thread_index];
+
+ vlib_process_start_switch_stack (vm, 0);
rv = (void *) clib_calljmp
((uword (*)(uword)) w->thread_function,
(uword) arg, w->thread_stack + VLIB_THREAD_STACK_SIZE);
{
clib_mem_main_t *mm = &clib_mem_main;
vlib_thread_main_t *tm = &vlib_thread_main;
+ pthread_t worker;
+ cpu_set_t cpuset;
void *(*fp_arg) (void *) = fp;
void *numa_heap;
}
}
- if (tm->cb.vlib_launch_thread_cb && !w->registration->use_pthreads)
- return tm->cb.vlib_launch_thread_cb (fp, (void *) w, cpu_id);
- else
- {
- pthread_t worker;
- cpu_set_t cpuset;
CPU_ZERO (&cpuset);
CPU_SET (cpu_id, &cpuset);
return clib_error_return_unix (0, "pthread_setaffinity_np");
return 0;
- }
}
static clib_error_t *
vm_clone->thread_index = worker_thread_index;
vm_clone->heap_base = w->thread_mheap;
- vm_clone->heap_aligned_base = (void *)
- (((uword) w->thread_mheap) & ~(VLIB_FRAME_ALIGN - 1));
+ vm_clone->heap_aligned_base =
+ (void *) (((uword) w->thread_mheap) &
+ ~(CLIB_CACHE_LINE_BYTES - 1));
vm_clone->pending_rpc_requests = 0;
vec_validate (vm_clone->pending_rpc_requests, 0);
_vec_len (vm_clone->pending_rpc_requests) = 0;
nm_clone->nodes_by_type[VLIB_NODE_TYPE_INTERNAL])
{
vlib_node_t *n = vlib_get_node (vm, rt->node_index);
- rt->thread_index = vm_clone->thread_index;
/* copy initial runtime_data from node */
if (n->runtime_data && n->runtime_data_bytes > 0)
clib_memcpy (rt->runtime_data, n->runtime_data,
vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT])
{
vlib_node_t *n = vlib_get_node (vm, rt->node_index);
- rt->thread_index = vm_clone->thread_index;
/* copy initial runtime_data from node */
if (n->runtime_data && n->runtime_data_bytes > 0)
clib_memcpy (rt->runtime_data, n->runtime_data,
nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT])
{
vlib_node_t *n = vlib_get_node (vm, rt->node_index);
- rt->thread_index = vm_clone->thread_index;
/* copy initial runtime_data from node */
if (n->runtime_data && n->runtime_data_bytes > 0)
clib_memcpy (rt->runtime_data, n->runtime_data,
CLIB_CACHE_LINE_BYTES);
/* Create per-thread frame freelist */
- nm_clone->frame_sizes = vec_new (vlib_frame_size_t, 1);
-#ifdef VLIB_SUPPORTS_ARBITRARY_SCALAR_SIZES
- nm_clone->frame_size_hash = hash_create (0, sizeof (uword));
-#endif
+ nm_clone->frame_sizes = 0;
nm_clone->node_by_error = nm->node_by_error;
/* Packet trace buffers are guaranteed to be empty, nothing to do here */
CLIB_CACHE_LINE_BYTES);
/* Switch to the stats segment ... */
- void *oldheap = vlib_stats_push_heap (0);
+ void *oldheap = vlib_stats_set_heap ();
vm_clone->error_main.counters =
vec_dup_aligned (vlib_get_first_main ()->error_main.counters,
CLIB_CACHE_LINE_BYTES);
- vlib_stats_pop_heap2 (vm_clone->error_main.counters,
- worker_thread_index, oldheap, 1);
+ clib_mem_set_heap (oldheap);
+ vlib_stats_update_error_vector (vm_clone->error_main.counters,
+ worker_thread_index, 1);
vm_clone->error_main.counters_last_clear = vec_dup_aligned (
vlib_get_first_main ()->error_main.counters_last_clear,
j = vec_len (vm->error_main.counters) - 1;
/* Switch to the stats segment ... */
- void *oldheap = vlib_stats_push_heap (0);
+ void *oldheap = vlib_stats_set_heap ();
vec_validate_aligned (old_counters, j, CLIB_CACHE_LINE_BYTES);
+ clib_mem_set_heap (oldheap);
vm_clone->error_main.counters = old_counters;
- vlib_stats_pop_heap2 (vm_clone->error_main.counters, vm_clone->thread_index,
- oldheap, 0);
+ vlib_stats_update_error_vector (vm_clone->error_main.counters,
+ vm_clone->thread_index, 0);
vec_validate_aligned (old_counters_all_clear, j, CLIB_CACHE_LINE_BYTES);
vm_clone->error_main.counters_last_clear = old_counters_all_clear;
vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_INTERNAL])
{
vlib_node_t *n = vlib_get_node (vm, rt->node_index);
- rt->thread_index = vm_clone->thread_index;
/* copy runtime_data, will be overwritten later for existing rt */
if (n->runtime_data && n->runtime_data_bytes > 0)
clib_memcpy_fast (rt->runtime_data, n->runtime_data,
vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT])
{
vlib_node_t *n = vlib_get_node (vm, rt->node_index);
- rt->thread_index = vm_clone->thread_index;
/* copy runtime_data, will be overwritten later for existing rt */
if (n->runtime_data && n->runtime_data_bytes > 0)
clib_memcpy_fast (rt->runtime_data, n->runtime_data,
vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT])
{
vlib_node_t *n = vlib_get_node (vm, rt->node_index);
- rt->thread_index = vm_clone->thread_index;
/* copy runtime_data, will be overwritten later for existing rt */
if (n->runtime_data && n->runtime_data_bytes > 0)
clib_memcpy_fast (rt->runtime_data, n->runtime_data,
vec_free (old_rt);
+ vec_free (nm_clone->processes);
nm_clone->processes = vec_dup_aligned (nm->processes,
CLIB_CACHE_LINE_BYTES);
nm_clone->node_by_error = nm->node_by_error;
* rebuilding the stat segment node clones from the
* stat thread...
*/
- vlib_stat_segment_lock ();
+ vlib_stats_segment_lock ();
/* Do stats elements on main thread */
worker_thread_node_runtime_update_internal ();
os_panic ();
}
}
- vlib_stat_segment_unlock ();
+ vlib_stats_segment_unlock ();
}
t_closed_total = now - vm->barrier_epoch;
{
vlib_global_main_t *vgm = vlib_get_global_main ();
vlib_worker_thread_t *w = (vlib_worker_thread_t *) arg;
- vlib_thread_main_t *tm = vlib_get_thread_main ();
vlib_main_t *vm = vlib_get_main ();
clib_error_t *e;
if (e)
clib_error_report (e);
- /* Wait until the dpdk init sequence is complete */
- while (tm->extern_thread_mgmt && tm->worker_thread_release == 0)
- vlib_worker_thread_barrier_check ();
-
vlib_worker_loop (vm);
}
fqm->node_index = node_index;
fqm->frame_queue_nelts = frame_queue_nelts;
- fqm->queue_hi_thresh = frame_queue_nelts - num_threads;
vec_validate (fqm->vlib_frame_queues, tm->n_vlib_mains - 1);
- vec_validate (fqm->per_thread_data, tm->n_vlib_mains - 1);
_vec_len (fqm->vlib_frame_queues) = 0;
for (i = 0; i < tm->n_vlib_mains; i++)
{
- vlib_frame_queue_per_thread_data_t *ptd;
fq = vlib_frame_queue_alloc (frame_queue_nelts);
vec_add1 (fqm->vlib_frame_queues, fq);
-
- ptd = vec_elt_at_index (fqm->per_thread_data, i);
- vec_validate (ptd->handoff_queue_elt_by_thread_index,
- tm->n_vlib_mains - 1);
- vec_validate_init_empty (ptd->congested_handoff_queue_by_thread_index,
- tm->n_vlib_mains - 1,
- (vlib_frame_queue_t *) (~0));
}
return (fqm - tm->frame_queue_mains);
}
-int
-vlib_thread_cb_register (struct vlib_main_t *vm, vlib_thread_callbacks_t * cb)
-{
- vlib_thread_main_t *tm = vlib_get_thread_main ();
-
- if (tm->extern_thread_mgmt)
- return -1;
-
- tm->cb.vlib_launch_thread_cb = cb->vlib_launch_thread_cb;
- tm->extern_thread_mgmt = 1;
- return 0;
-}
-
void
vlib_process_signal_event_mt_helper (vlib_process_signal_event_mt_args_t *
args)
show_clock_command_fn (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
- int i;
int verbose = 0;
clib_timebase_t _tb, *tb = &_tb;
verbose, format_clib_timebase_time,
clib_timebase_now (tb));
- if (vlib_get_n_threads () == 1)
- return 0;
-
vlib_cli_output (vm, "Time last barrier release %.9f",
vm->time_last_barrier_release);
- for (i = 1; i < vlib_get_n_threads (); i++)
+ foreach_vlib_main ()
{
- vlib_main_t *ovm = vlib_get_main_by_index (i);
- if (ovm == 0)
- continue;
-
- vlib_cli_output (vm, "%d: %U", i, format_clib_time, &ovm->clib_time,
- verbose);
-
- vlib_cli_output (
- vm, "Thread %d offset %.9f error %.9f", i, ovm->time_offset,
- vm->time_last_barrier_release - ovm->time_last_barrier_release);
+ vlib_cli_output (vm, "%d: %U", this_vlib_main->thread_index,
+ format_clib_time, &this_vlib_main->clib_time, verbose);
+
+ vlib_cli_output (vm, "Thread %d offset %.9f error %.9f",
+ this_vlib_main->thread_index,
+ this_vlib_main->time_offset,
+ vm->time_last_barrier_release -
+ this_vlib_main->time_last_barrier_release);
}
return 0;
}