+static inline void
+update_serialized_nodes (stats_main_t * sm)
+{
+ int i;
+ vlib_main_t *vm = vlib_mains[0];
+ ssvm_private_t *ssvmp = &sm->stat_segment;
+ ssvm_shared_header_t *shared_header;
+ void *oldheap;
+ stat_segment_directory_entry_t *ep;
+ hash_pair_t *hp;
+ u8 *name_copy;
+
+ ASSERT (ssvmp && ssvmp->sh);
+
+ vec_reset_length (sm->serialized_nodes);
+
+ shared_header = ssvmp->sh;
+
+ oldheap = ssvm_push_heap (shared_header);
+
+ clib_spinlock_lock (sm->stat_segment_lockp);
+
+ vlib_node_get_nodes (0 /* vm, for barrier sync */ ,
+ (u32) ~ 0 /* all threads */ ,
+ 1 /* include stats */ ,
+ 0 /* barrier sync */ ,
+ &sm->node_dups, &sm->stat_vms);
+
+ sm->serialized_nodes = vlib_node_serialize (vm, sm->node_dups,
+ sm->serialized_nodes,
+ 0 /* include nexts */ ,
+ 1 /* include stats */ );
+
+ hp = hash_get_pair (sm->counter_vector_by_name, "serialized_nodes");
+ if (hp)
+ {
+ name_copy = (u8 *) hp->key;
+ ep = (stat_segment_directory_entry_t *) (hp->value[0]);
+
+ if (ep->value != sm->serialized_nodes)
+ {
+ ep->value = sm->serialized_nodes;
+ /* Warn clients to refresh any pointers they might be holding */
+ shared_header->opaque[STAT_SEGMENT_OPAQUE_EPOCH] = (void *)
+ ((u64) shared_header->opaque[STAT_SEGMENT_OPAQUE_EPOCH] + 1);
+ }
+ }
+ else
+ {
+ name_copy = format (0, "%s%c", "serialized_nodes", 0);
+ ep = clib_mem_alloc (sizeof (*ep));
+ ep->type = STAT_DIR_TYPE_SERIALIZED_NODES;
+ ep->value = sm->serialized_nodes;
+ hash_set_mem (sm->counter_vector_by_name, name_copy, ep);
+
+ /* Reset the client hash table pointer */
+ shared_header->opaque[STAT_SEGMENT_OPAQUE_DIR]
+ = sm->counter_vector_by_name;
+
+ /* Warn clients to refresh any pointers they might be holding */
+ shared_header->opaque[STAT_SEGMENT_OPAQUE_EPOCH] = (void *)
+ ((u64) shared_header->opaque[STAT_SEGMENT_OPAQUE_EPOCH] + 1);
+ }
+
+ clib_spinlock_unlock (sm->stat_segment_lockp);
+ ssvm_pop_heap (oldheap);
+}
+
+/*
+ * Called by stats_thread_fn, in stats.c, which runs in a
+ * separate pthread, which won't halt the parade
+ * in single-forwarding-core cases.
+ */
+
+void
+do_stat_segment_updates (stats_main_t * sm)