X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fthreads.h;h=97df3d253a0792af68229888e84d7596d13d49c0;hb=52fa5f21b;hp=eb31edc2706c53ad8480822b0561e799cbbed5aa;hpb=6ffb7c61899eb782416cbd2f117042a583f189f7;p=vpp.git diff --git a/src/vlib/threads.h b/src/vlib/threads.h index eb31edc2706..97df3d253a0 100644 --- a/src/vlib/threads.h +++ b/src/vlib/threads.h @@ -19,8 +19,6 @@ #include #include -extern vlib_main_t **vlib_mains; - void vlib_set_thread_name (char *name); /* arg is actually a vlib__thread_t * */ @@ -66,21 +64,18 @@ typedef struct vlib_thread_registration_ #define VLIB_LOG2_THREAD_STACK_SIZE (21) #define VLIB_THREAD_STACK_SIZE (1<parked_at_barrier == 1); \ - if (this_vlib_main) \ - vec_add1 (__vlib_mains, this_vlib_main); \ - } \ - \ - for (ii = 0; ii < vec_len (__vlib_mains); ii++) \ - { \ - this_vlib_main = __vlib_mains[ii]; \ - /* body uses this_vlib_main... */ \ - (body); \ - } \ - vec_free (__vlib_mains); \ -} while (0); + vlib_main_t *vm; + u32 index = ii - (vlib_main_t *) 0; + + if (index >= vec_len (vlib_global_main.vlib_mains)) + return 0; + + *p = vm = vlib_global_main.vlib_mains[index]; + ASSERT (index == 0 || vm->parked_at_barrier == 1); + return 1; +} + +#define foreach_vlib_main() \ + for (vlib_main_t *ii = 0, *this_vlib_main; \ + __foreach_vlib_main_helper (ii, &this_vlib_main); ii++) \ + if (this_vlib_main) #define foreach_sched_policy \ _(SCHED_OTHER, OTHER, "other") \ @@ -277,13 +241,6 @@ typedef enum SCHED_POLICY_N, } sched_policy_t; -typedef struct -{ - clib_error_t *(*vlib_launch_thread_cb) (void *fp, vlib_worker_thread_t * w, - unsigned cpu_id); - clib_error_t *(*vlib_thread_set_lcore_cb) (u32 thread, u16 cpu); -} vlib_thread_callbacks_t; - typedef struct { /* Link list of registrations, built by constructors */ @@ -296,10 +253,6 @@ typedef struct vlib_worker_thread_t *worker_threads; - /* - * Launch all threads as pthreads, - * not eal_rte_launch (strict affinity) threads - */ int use_pthreads; /* Number of vlib_main / vnet_main clones */ @@ -341,10 +294,6 @@ typedef struct /* scheduling policy priority */ u32 sched_priority; - /* callbacks */ - vlib_thread_callbacks_t cb; - int extern_thread_mgmt; - /* NUMA-bound heap size */ uword numa_heap_size; @@ -402,6 +351,7 @@ vlib_worker_thread_barrier_check (void) { if (PREDICT_FALSE (*vlib_worker_threads->wait_at_barrier)) { + vlib_global_main_t *vgm = vlib_get_global_main (); vlib_main_t *vm = vlib_get_main (); u32 thread_index = vm->thread_index; f64 t = vlib_time_now (vm); @@ -425,8 +375,7 @@ vlib_worker_thread_barrier_check (void) u32 thread_index; } __clib_packed *ed; - ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e, - w->elog_track); + ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e, w->elog_track); ed->thread_index = thread_index; } @@ -449,7 +398,7 @@ vlib_worker_thread_barrier_check (void) f64 now; vm->time_offset = 0.0; now = vlib_time_now (vm); - vm->time_offset = vlib_global_main.time_last_barrier_release - now; + vm->time_offset = vgm->vlib_mains[0]->time_last_barrier_release - now; vm->time_last_barrier_release = vlib_time_now (vm); } @@ -503,8 +452,7 @@ vlib_worker_thread_barrier_check (void) u32 duration; } __clib_packed *ed; - ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e, - w->elog_track); + ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e, w->elog_track); ed->thread_index = thread_index; ed->duration = (int) (1000000.0 * t); } @@ -534,97 +482,7 @@ vlib_thread_is_main_w_barrier (void) && vlib_worker_threads->wait_at_barrier[0]))); } -static inline void -vlib_put_frame_queue_elt (vlib_frame_queue_elt_t * hf) -{ - CLIB_MEMORY_BARRIER (); - hf->valid = 1; -} - -static inline vlib_frame_queue_elt_t * -vlib_get_frame_queue_elt (u32 frame_queue_index, u32 index) -{ - vlib_frame_queue_t *fq; - vlib_frame_queue_elt_t *elt; - vlib_thread_main_t *tm = &vlib_thread_main; - vlib_frame_queue_main_t *fqm = - vec_elt_at_index (tm->frame_queue_mains, frame_queue_index); - u64 new_tail; - - fq = fqm->vlib_frame_queues[index]; - ASSERT (fq); - - new_tail = clib_atomic_add_fetch (&fq->tail, 1); - - /* Wait until a ring slot is available */ - while (new_tail >= fq->head_hint + fq->nelts) - vlib_worker_thread_barrier_check (); - - elt = fq->elts + (new_tail & (fq->nelts - 1)); - - /* this would be very bad... */ - while (elt->valid) - ; - - elt->msg_type = VLIB_FRAME_QUEUE_ELT_DISPATCH_FRAME; - elt->last_n_vectors = elt->n_vectors = 0; - - return elt; -} - -static inline vlib_frame_queue_t * -is_vlib_frame_queue_congested (u32 frame_queue_index, - u32 index, - u32 queue_hi_thresh, - vlib_frame_queue_t ** - handoff_queue_by_worker_index) -{ - vlib_frame_queue_t *fq; - vlib_thread_main_t *tm = &vlib_thread_main; - vlib_frame_queue_main_t *fqm = - vec_elt_at_index (tm->frame_queue_mains, frame_queue_index); - - fq = handoff_queue_by_worker_index[index]; - if (fq != (vlib_frame_queue_t *) (~0)) - return fq; - - fq = fqm->vlib_frame_queues[index]; - ASSERT (fq); - - if (PREDICT_FALSE (fq->tail >= (fq->head_hint + queue_hi_thresh))) - { - /* a valid entry in the array will indicate the queue has reached - * the specified threshold and is congested - */ - handoff_queue_by_worker_index[index] = fq; - fq->enqueue_full_events++; - return fq; - } - - return NULL; -} - -static inline vlib_frame_queue_elt_t * -vlib_get_worker_handoff_queue_elt (u32 frame_queue_index, - u32 vlib_worker_index, - vlib_frame_queue_elt_t ** - handoff_queue_elt_by_worker_index) -{ - vlib_frame_queue_elt_t *elt; - - if (handoff_queue_elt_by_worker_index[vlib_worker_index]) - return handoff_queue_elt_by_worker_index[vlib_worker_index]; - - elt = vlib_get_frame_queue_elt (frame_queue_index, vlib_worker_index); - - handoff_queue_elt_by_worker_index[vlib_worker_index] = elt; - - return elt; -} - u8 *vlib_thread_stack_init (uword thread_index); -int vlib_thread_cb_register (struct vlib_main_t *vm, - vlib_thread_callbacks_t * cb); extern void *rpc_call_main_thread_cb_fn; void @@ -634,6 +492,17 @@ void vlib_rpc_call_main_thread (void *function, u8 * args, u32 size); void vlib_get_thread_core_numa (vlib_worker_thread_t * w, unsigned cpu_id); vlib_thread_main_t *vlib_get_thread_main_not_inline (void); +/** + * Force workers sync from within worker + * + * Must be paired with @ref vlib_workers_continue + */ +void vlib_workers_sync (void); +/** + * Release barrier after workers sync + */ +void vlib_workers_continue (void); + #endif /* included_vlib_threads_h */ /*