static fib_walk_history_t fib_walk_history[HISTORY_N_WALKS];
u8*
-format_fib_walk_priority (u8 *s, va_list ap)
+format_fib_walk_priority (u8 *s, va_list *ap)
{
- fib_walk_priority_t prio = va_arg(ap, fib_walk_priority_t);
+ fib_walk_priority_t prio = va_arg(*ap, fib_walk_priority_t);
ASSERT(prio < FIB_WALK_PRIORITY_NUM);
return (format(s, "%s", fib_walk_priority_names[prio]));
}
static u8*
-format_fib_walk_queue_stats (u8 *s, va_list ap)
+format_fib_walk_queue_stats (u8 *s, va_list *ap)
{
- fib_walk_queue_stats_t wqs = va_arg(ap, fib_walk_queue_stats_t);
+ fib_walk_queue_stats_t wqs = va_arg(*ap, fib_walk_queue_stats_t);
ASSERT(wqs < FIB_WALK_QUEUE_STATS_NUM);
static fib_walk_advance_rc_t
fib_walk_advance (fib_node_index_t fwi)
{
- fib_node_back_walk_ctx_t *ctx, *old;
fib_node_back_walk_rc_t wrc;
fib_node_ptr_t sibling;
fib_walk_t *fwalk;
+ uint n_ctxs, ii;
int more_elts;
/*
if (more_elts)
{
- old = fwalk->fw_ctx;
- vec_foreach(ctx, fwalk->fw_ctx)
- {
- wrc = fib_node_back_walk_one(&sibling, ctx);
+ /*
+ * loop through the backwalk contexts. This can grow in length
+ * as walks on the same object meet each other. Order is preserved so the
+ * most recently started walk as at the back of the vector.
+ */
+ ii = 0;
+ n_ctxs = vec_len(fwalk->fw_ctx);
+ while (ii < n_ctxs)
+ {
+ wrc = fib_node_back_walk_one(&sibling, &fwalk->fw_ctx[ii]);
+
+ ii++;
fwalk = fib_walk_get(fwi);
fwalk->fw_n_visits++;
*/
return (FIB_WALK_ADVANCE_MERGE);
}
- if (old != fwalk->fw_ctx)
- {
- /*
- * nasty re-entrant addition of a walk has realloc'd the vector
- * break out
- */
- return (FIB_WALK_ADVANCE_MERGE);
- }
+
+ /*
+ * re-evaluate the number of backwalk contexts we need to process.
+ */
+ n_ctxs = vec_len(fwalk->fw_ctx);
}
/*
* move foward to the next node to visit
* @brief Durations for the sleep types
*/
static f64 fib_walk_sleep_duration[] = {
- [FIB_WALK_LONG_SLEEP] = 1e-3,
+ /**
+ * Long sleep when there is no more work, i.e. the queues are empty.
+ * This is a sleep (as opposed to a wait for event) just to be sure we
+ * are not missing events by sleeping forever.
+ */
+ [FIB_WALK_LONG_SLEEP] = 2,
+
+ /**
+ * Short sleep. There is work left in the queues. We are yielding the CPU
+ * momentarily.
+ */
[FIB_WALK_SHORT_SLEEP] = 1e-8,
};
}
static u8*
-format_fib_walk (u8* s, va_list ap)
+format_fib_walk (u8* s, va_list *ap)
{
- fib_node_index_t fwi = va_arg(ap, fib_node_index_t);
+ fib_node_index_t fwi = va_arg(*ap, fib_node_index_t);
fib_walk_t *fwalk;
fwalk = fib_walk_get(fwi);