Commit bd9a48e7 authored by Rusty Russell's avatar Rusty Russell

timer: better dump code.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 897219d6
...@@ -389,50 +389,84 @@ past_levels: ...@@ -389,50 +389,84 @@ past_levels:
} }
#ifdef CCAN_TIMER_DEBUG #ifdef CCAN_TIMER_DEBUG
void timers_dump(const struct timers *timers, FILE *fp) static void dump_bucket_stats(FILE *fp, const struct list_head *h)
{ {
unsigned int l, i; unsigned long long min, max, num;
uint64_t min, max, num;
struct timer *t; struct timer *t;
if (!fp) if (list_empty(h)) {
fp = stderr; printf("\n");
return;
fprintf(fp, "Base: %llu\n", timers->base);
for (l = 0; timers->level[l] && l < ARRAY_SIZE(timers->level); l++) {
fprintf(fp, "Level %i (+%llu):\n",
l, (uint64_t)1 << (TIMER_LEVEL_BITS * l));
for (i = 0; i < (1 << TIMER_LEVEL_BITS); i++) {
if (list_empty(&timers->level[l]->list[i]))
continue;
min = -1ULL;
max = 0;
num = 0;
list_for_each(&timers->level[l]->list[i], t, list) {
if (t->time < min)
min = t->time;
if (t->time > max)
max = t->time;
num++;
}
fprintf(stderr, " %llu (+%llu-+%llu)\n",
num, min - timers->base, max - timers->base);
}
} }
min = -1ULL; min = -1ULL;
max = 0; max = 0;
num = 0; num = 0;
list_for_each(&timers->far, t, list) { list_for_each(h, t, list) {
if (t->time < min) if (t->time < min)
min = t->time; min = t->time;
if (t->time > max) if (t->time > max)
max = t->time; max = t->time;
num++; num++;
} }
fprintf(stderr, "Far: %llu (%llu-%llu)\n", num, min, max); fprintf(fp, " %llu (%llu-%llu)\n",
num, min, max);
}
void timers_dump(const struct timers *timers, FILE *fp)
{
unsigned int l, i, off;
unsigned long long base;
if (!fp)
fp = stderr;
fprintf(fp, "Base: %llu\n", (unsigned long long)timers->base);
if (!timers->level[0])
goto past_levels;
fprintf(fp, "Level 0:\n");
/* First level is simple. */
off = timers->base % PER_LEVEL;
for (i = 0; i < PER_LEVEL; i++) {
const struct list_head *h;
fprintf(fp, " Bucket %llu (%lu):",
(i+off) % PER_LEVEL, timers->base + i);
h = &timers->level[0]->list[(i+off) % PER_LEVEL];
dump_bucket_stats(fp, h);
}
/* For other levels, "current" bucket has been emptied, and may contain
* entries for the current + level_size bucket. */
for (l = 1; l < ARRAY_SIZE(timers->level) && timers->level[l]; l++) {
uint64_t per_bucket = 1ULL << (TIMER_LEVEL_BITS * l);
off = ((timers->base >> (l*TIMER_LEVEL_BITS)) % PER_LEVEL);
/* We start at *next* bucket. */
base = (timers->base & ~(per_bucket - 1)) + per_bucket;
fprintf(fp, "Level %u:\n", l);
for (i = 1; i <= PER_LEVEL; i++) {
const struct list_head *h;
fprintf(fp, " Bucket %llu (%llu - %llu):",
(i+off) % PER_LEVEL,
base, base + per_bucket - 1);
h = &timers->level[l]->list[(i+off) % PER_LEVEL];
dump_bucket_stats(fp, h);
base += per_bucket;
}
}
past_levels:
if (!list_empty(&timers->far)) {
fprintf(fp, "Far timers:");
dump_bucket_stats(fp, &timers->far);
}
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment