api: refactor vlibmemory
[vpp.git] / src / vlib / node.c
index e6739dc..17dd2ea 100644 (file)
@@ -543,6 +543,60 @@ vlib_register_all_static_nodes (vlib_main_t * vm)
     }
 }
 
+vlib_node_t ***
+vlib_node_get_nodes (vlib_main_t * vm, u32 max_threads, int include_stats)
+{
+  vlib_node_main_t *nm = &vm->node_main;
+  vlib_node_t *n;
+  static vlib_node_t ***node_dups;
+  vlib_node_t **nodes;
+  static vlib_main_t **stat_vms;
+  vlib_main_t *stat_vm;
+  uword i, j;
+  u32 threads_to_serialize;
+
+  vec_reset_length (node_dups);
+
+  if (vec_len (stat_vms) == 0)
+    {
+      for (i = 0; i < vec_len (vlib_mains); i++)
+       {
+         stat_vm = vlib_mains[i];
+         if (stat_vm)
+           vec_add1 (stat_vms, stat_vm);
+       }
+    }
+
+  threads_to_serialize = clib_min (max_threads, vec_len (stat_vms));
+
+  /*
+   * Barrier sync across stats scraping.
+   * Otherwise, the counts will be grossly inaccurate.
+   */
+  vlib_worker_thread_barrier_sync (vm);
+
+  for (j = 0; j < threads_to_serialize; j++)
+    {
+      stat_vm = stat_vms[j];
+      nm = &stat_vm->node_main;
+
+      if (include_stats)
+       {
+         for (i = 0; i < vec_len (nm->nodes); i++)
+           {
+             n = nm->nodes[i];
+             vlib_node_sync_stats (stat_vm, n);
+           }
+       }
+
+      nodes = vec_dup (nm->nodes);
+      vec_add1 (node_dups, nodes);
+    }
+  vlib_worker_thread_barrier_release (vm);
+
+  return node_dups;
+}
+
 clib_error_t *
 vlib_node_main_init (vlib_main_t * vm)
 {