+
+uword
+perfmon_dispatch_wrapper_metrics (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame)
+{
+ perfmon_main_t *pm = &perfmon_main;
+ perfmon_thread_runtime_t *rt =
+ vec_elt_at_index (pm->thread_runtimes, vm->thread_index);
+ perfmon_node_stats_t *s =
+ vec_elt_at_index (rt->node_stats, node->node_index);
+
+ u8 n_events = rt->n_events;
+
+ u64 before[PERF_MAX_EVENTS];
+ int pmc_index[PERF_MAX_EVENTS];
+ uword rv;
+
+ clib_prefetch_load (s);
+
+ switch (n_events)
+ {
+ default:
+ case 7:
+ pmc_index[6] = perfmon_metric_index (rt->bundle, 6);
+ case 6:
+ pmc_index[5] = perfmon_metric_index (rt->bundle, 5);
+ case 5:
+ pmc_index[4] = perfmon_metric_index (rt->bundle, 4);
+ case 4:
+ pmc_index[3] = perfmon_metric_index (rt->bundle, 3);
+ case 3:
+ pmc_index[2] = perfmon_metric_index (rt->bundle, 2);
+ case 2:
+ pmc_index[1] = perfmon_metric_index (rt->bundle, 1);
+ case 1:
+ pmc_index[0] = perfmon_metric_index (rt->bundle, 0);
+ break;
+ }
+
+ perfmon_read_pmcs (&before[0], pmc_index, n_events);
+ rv = node->function (vm, node, frame);
+
+ clib_memcpy_fast (&s->t[0].value[0], &before, sizeof (before));
+ perfmon_read_pmcs (&s->t[1].value[0], pmc_index, n_events);
+
+ if (rv == 0)
+ return rv;
+
+ s->n_calls += 1;
+ s->n_packets += rv;
+
+ return rv;
+}