diff --git a/doc/dox/programs/pw-top.1.md b/doc/dox/programs/pw-top.1.md index c57c33bc4..460fd80d4 100644 --- a/doc/dox/programs/pw-top.1.md +++ b/doc/dox/programs/pw-top.1.md @@ -177,6 +177,16 @@ Names are prefixed by *+* when they are linked to a driver (entry above with no +) \endparblock +# COMMANDS + +The following keys can be used in the interactive mode: + +\par q +Quit + +\par c +Clear the ERR counters. This does *not* clear the counters globally, +it will only reset the counters in this instance of *pw-top*. # OPTIONS diff --git a/src/tools/pw-top.c b/src/tools/pw-top.c index fc4da9239..d92462fa1 100644 --- a/src/tools/pw-top.c +++ b/src/tools/pw-top.c @@ -53,7 +53,9 @@ struct node { char name[MAX_NAME+1]; enum pw_node_state state; struct measurement measurement; + uint32_t measurement_base; struct driver info; + uint32_t info_base; struct node *driver; uint32_t generation; char format[MAX_FORMAT+1]; @@ -486,8 +488,9 @@ static const char *state_as_string(enum pw_node_state state, uint32_t transport) return "!"; } -static void print_node(struct data *d, struct driver *i, struct node *n, int y) +static void print_node(struct data *d, struct node *dr, struct node *n, int y) { + struct driver *i = &dr->info; char buf1[64]; char buf2[64]; char buf3[64]; @@ -534,7 +537,8 @@ static void print_node(struct data *d, struct driver *i, struct node *n, int y) print_perc(buf3, active, 64, waiting, quantum), print_perc(buf4, active, 64, busy, quantum), n->measurement.xrun_count == XRUN_INVALID ? - i->xrun_count : n->measurement.xrun_count, + i->xrun_count - dr->info_base : + n->measurement.xrun_count - n->measurement_base, active ? n->format : "", n->driver == n ? "" : " + ", n->name); @@ -570,7 +574,7 @@ static void do_refresh(struct data *d, bool force_refresh) if (n->driver != n) continue; - print_node(d, &n->info, n, y++); + print_node(d, n, n, y++); if(!d->batch_mode && y > LINES) break; @@ -581,7 +585,7 @@ static void do_refresh(struct data *d, bool force_refresh) if (f->driver != n || f == n) continue; - print_node(d, &n->info, f, y++); + print_node(d, n, f, y++); if(!d->batch_mode && y > LINES) break; @@ -612,6 +616,16 @@ static void do_timeout(void *data, uint64_t expirations) do_refresh(d, true); } +static void reset_xruns(struct data *d) +{ + struct node *n; + spa_list_for_each(n, &d->node_list, link) { + n->info_base = n->info.xrun_count; + n->measurement_base = n->measurement.xrun_count; + } + do_refresh(d, true); +} + static void profiler_profile(void *data, const struct spa_pod *pod) { struct data *d = data; @@ -788,6 +802,9 @@ static void do_handle_io(void *data, int fd, uint32_t mask) case 'q': pw_main_loop_quit(d->loop); break; + case 'c': + reset_xruns(d); + break; default: do_refresh(d, !d->batch_mode); break;