X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fthreads.h;h=e5a1f6d7ec5d549a2f00198779e72c9a34832544;hb=aaa2a89a3d927683af46793b6ad666e8ff591de9;hp=28a81f78712dfdd30d3693d6bfdbaf0e904dafa6;hpb=92ccf9bcd2692b4b415f31044560c735d639a35c;p=vpp.git diff --git a/src/vlib/threads.h b/src/vlib/threads.h index 28a81f78712..e5a1f6d7ec5 100644 --- a/src/vlib/threads.h +++ b/src/vlib/threads.h @@ -45,40 +45,21 @@ typedef struct vlib_thread_registration_ uword *coremask; } vlib_thread_registration_t; -/* - * Frames have their cpu / vlib_main_t index in the low-order N bits - * Make VLIB_MAX_CPUS a power-of-two, please... - */ - -#ifndef VLIB_MAX_CPUS -#define VLIB_MAX_CPUS 256 -#endif - -#if VLIB_MAX_CPUS > CLIB_MAX_MHEAPS -#error Please increase number of per-cpu mheaps -#endif - -#define VLIB_CPU_MASK (VLIB_MAX_CPUS - 1) /* 0x3f, max */ -#define VLIB_OFFSET_MASK (~VLIB_CPU_MASK) - #define VLIB_LOG2_THREAD_STACK_SIZE (21) #define VLIB_THREAD_STACK_SIZE (1<= 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 = vlib_global_main.vlib_mains[0]; \ - (ii - (vlib_main_t *) 0) < vec_len (vlib_global_main.vlib_mains); \ - ii++, this_vlib_main = \ - vlib_global_main.vlib_mains[ii - (vlib_main_t *) 0]) \ - if (CLIB_ASSERT_ENABLE && \ - !(ii == 0 || \ - (this_vlib_main && this_vlib_main->parked_at_barrier == 1))) \ - ASSERT (0); \ - else if (this_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") \ @@ -263,13 +229,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 */ @@ -282,10 +241,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 */ @@ -327,10 +282,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; @@ -519,97 +470,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 @@ -619,6 +480,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 */ /*