diff options
Diffstat (limited to 'src/vlib')
-rw-r--r-- | src/vlib/stats/init.c | 2 | ||||
-rw-r--r-- | src/vlib/stats/stats.c | 33 | ||||
-rw-r--r-- | src/vlib/stats/stats.h | 2 |
3 files changed, 32 insertions, 5 deletions
diff --git a/src/vlib/stats/init.c b/src/vlib/stats/init.c index d81916a288d..d24c1580a88 100644 --- a/src/vlib/stats/init.c +++ b/src/vlib/stats/init.c @@ -88,6 +88,8 @@ vlib_stats_init (vlib_main_t *vm) shared_header->base = memaddr; sm->stat_segment_lockp = clib_mem_alloc (sizeof (clib_spinlock_t)); + sm->locking_thread_index = ~0; + sm->n_locks = 0; clib_spinlock_init (sm->stat_segment_lockp); oldheap = clib_mem_set_heap (sm->heap); diff --git a/src/vlib/stats/stats.c b/src/vlib/stats/stats.c index 19edaf0866d..97f84006eaf 100644 --- a/src/vlib/stats/stats.c +++ b/src/vlib/stats/stats.c @@ -7,24 +7,47 @@ vlib_stats_main_t vlib_stats_main; -/* - * Used only by VPP writers - */ - void vlib_stats_segment_lock (void) { + vlib_main_t *vm = vlib_get_main (); vlib_stats_segment_t *sm = vlib_stats_get_segment (); + + /* already locked by us */ + if (sm->shared_header->in_progress && + vm->thread_index == sm->locking_thread_index) + goto done; + + ASSERT (sm->locking_thread_index == ~0); + ASSERT (sm->shared_header->in_progress == 0); + ASSERT (sm->n_locks == 0); + clib_spinlock_lock (sm->stat_segment_lockp); + sm->shared_header->in_progress = 1; + sm->locking_thread_index = vm->thread_index; +done: + sm->n_locks++; } void vlib_stats_segment_unlock (void) { + vlib_main_t *vm = vlib_get_main (); vlib_stats_segment_t *sm = vlib_stats_get_segment (); + + ASSERT (sm->shared_header->in_progress == 1); + ASSERT (sm->locking_thread_index == vm->thread_index); + ASSERT (sm->n_locks > 0); + + sm->n_locks--; + + if (sm->n_locks > 0) + return; + sm->shared_header->epoch++; - sm->shared_header->in_progress = 0; + __atomic_store_n (&sm->shared_header->in_progress, 0, __ATOMIC_RELEASE); + sm->locking_thread_index = ~0; clib_spinlock_unlock (sm->stat_segment_lockp); } diff --git a/src/vlib/stats/stats.h b/src/vlib/stats/stats.h index 25d7c4ba484..faaa37a7ec2 100644 --- a/src/vlib/stats/stats.h +++ b/src/vlib/stats/stats.h @@ -82,6 +82,8 @@ typedef struct f64 update_interval; clib_spinlock_t *stat_segment_lockp; + u32 locking_thread_index; + u32 n_locks; clib_socket_t *socket; u8 *socket_name; ssize_t memory_size; |