Add callback multiplex support

Change-Id: Iddeb3a1b0e20706e72ec8f74dabc60b342f003ba
Signed-off-by: Dave Barach <dave@barachs.net>
diff --git a/src/vlib/main.c b/src/vlib/main.c
index 759c1d0..b6006e8 100644
--- a/src/vlib/main.c
+++ b/src/vlib/main.c
@@ -687,9 +687,9 @@
 {
   *pmc0 = 0;
   *pmc1 = 0;
-  if (PREDICT_FALSE (vm->vlib_node_runtime_perf_counter_cb != 0))
-    (*vm->vlib_node_runtime_perf_counter_cb) (vm, pmc0, pmc1, node,
-					      frame, before_or_after);
+  if (PREDICT_FALSE (vec_len (vm->vlib_node_runtime_perf_counter_cbs) != 0))
+    clib_call_callbacks (vm->vlib_node_runtime_perf_counter_cbs, vm, pmc0,
+			 pmc1, node, frame, before_or_after);
 }
 
 always_inline void
@@ -1760,9 +1760,8 @@
 	      else
 		frame_queue_check_counter--;
 	    }
-	  if (PREDICT_FALSE (vm->worker_thread_main_loop_callback != 0))
-	    ((void (*)(vlib_main_t *)) vm->worker_thread_main_loop_callback)
-	      (vm);
+	  if (PREDICT_FALSE (vec_len (vm->worker_thread_main_loop_callbacks)))
+	    clib_call_callbacks (vm->worker_thread_main_loop_callbacks, vm);
 	}
 
       /* Process pre-input nodes. */
diff --git a/src/vlib/main.h b/src/vlib/main.h
index 42f0c51..9b63116 100644
--- a/src/vlib/main.h
+++ b/src/vlib/main.h
@@ -94,11 +94,14 @@
   u32 node_counts_per_main_loop[2];
 
   /* Main loop hw / sw performance counters */
-  void (*vlib_node_runtime_perf_counter_cb) (struct vlib_main_t *,
-					     u64 *, u64 *,
-					     vlib_node_runtime_t *,
-					     vlib_frame_t *, int);
-
+  void (**vlib_node_runtime_perf_counter_cbs) (struct vlib_main_t *,
+					       u64 *, u64 *,
+					       vlib_node_runtime_t *,
+					       vlib_frame_t *, int);
+  void (**vlib_node_runtime_perf_counter_cb_tmp) (struct vlib_main_t *,
+						  u64 *, u64 *,
+						  vlib_node_runtime_t *,
+						  vlib_frame_t *, int);
   /* Every so often we switch to the next counter. */
 #define VLIB_LOG2_MAIN_LOOPS_PER_STATS_UPDATE 7
 
@@ -215,7 +218,10 @@
   u8 **argv;
 
   /* Top of (worker) dispatch loop callback */
-  volatile void (*worker_thread_main_loop_callback) (struct vlib_main_t *);
+  void (**volatile worker_thread_main_loop_callbacks) (struct vlib_main_t *);
+  void (**volatile worker_thread_main_loop_callback_tmp)
+    (struct vlib_main_t *);
+  clib_spinlock_t worker_thread_main_loop_callback_lock;
 
   /* debugging */
   volatile int parked_at_barrier;
diff --git a/src/vlib/vlib.h b/src/vlib/vlib.h
index b5fe47b..8f59cae 100644
--- a/src/vlib/vlib.h
+++ b/src/vlib/vlib.h
@@ -42,6 +42,7 @@
 
 #include <vppinfra/clib.h>
 #include <vppinfra/elf_clib.h>
+#include <vppinfra/callback.h>
 
 /* Generic definitions. */
 #include <vlib/defs.h>