stats: support recursive locking 39/35639/3
authorDamjan Marion <damarion@cisco.com>
Mon, 14 Mar 2022 12:04:38 +0000 (13:04 +0100)
committerFlorin Coras <florin.coras@gmail.com>
Mon, 14 Mar 2022 18:33:32 +0000 (18:33 +0000)
Type: improvement
Change-Id: I85dd3d34bcb175dd68dda34a58cd454848a0fc2b
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vlib/stats/init.c
src/vlib/stats/stats.c
src/vlib/stats/stats.h

index d81916a..d24c158 100644 (file)
@@ -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);
index 19edaf0..97f8400 100644 (file)
@@ -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);
 }
 
index 25d7c4b..faaa37a 100644 (file)
@@ -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;