diff options
Diffstat (limited to 'src/vlib/threads.c')
-rw-r--r-- | src/vlib/threads.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/vlib/threads.c b/src/vlib/threads.c index 4df550e61fb..d5096c8cd18 100644 --- a/src/vlib/threads.c +++ b/src/vlib/threads.c @@ -1444,6 +1444,18 @@ vlib_worker_thread_initial_barrier_sync_and_release (vlib_main_t * vm) *vlib_worker_threads->wait_at_barrier = 0; } +/** + * Return true if the wroker thread barrier is held + */ +u8 +vlib_worker_thread_barrier_held (void) +{ + if (vec_len (vlib_mains) < 2) + return (1); + + return (*vlib_worker_threads->wait_at_barrier == 1); +} + void vlib_worker_thread_barrier_sync_int (vlib_main_t * vm, const char *func_name) { @@ -1647,6 +1659,41 @@ vlib_worker_thread_barrier_release (vlib_main_t * vm) vm->clib_time.last_cpu_time, 1 /* leave */ ); } +/** + * Wait until each of the workers has been once around the track + */ +void +vlib_worker_wait_one_loop (void) +{ + ASSERT (vlib_get_thread_index () == 0); + + if (vec_len (vlib_mains) < 2) + return; + + if (vlib_worker_thread_barrier_held ()) + return; + + u32 *counts = 0; + u32 ii; + + vec_validate (counts, vec_len (vlib_mains) - 1); + + /* record the current loop counts */ + vec_foreach_index (ii, vlib_mains) + counts[ii] = vlib_mains[ii]->main_loop_count; + + /* spin until each changes, apart from the main thread, or we'd be + * a while */ + for (ii = 1; ii < vec_len (counts); ii++) + { + while (counts[ii] == vlib_mains[ii]->main_loop_count) + CLIB_PAUSE (); + } + + vec_free (counts); + return; +} + /* * Check the frame queue to see if any frames are available. * If so, pull the packets off the frames and put them to |