From: Scott Cheloha Subject: Re: systat(1): iostat: compute rates with elapsed time To: tech@openbsd.org Date: Mon, 8 Apr 2024 22:44:50 -0500 On Thu, Apr 04, 2024 at 02:18:54PM -0500, Scott Cheloha wrote: > In TIME mode, the iostat view sets etime to naptime before computing > rates. This is wrong. The elapsed time is never exactly naptime. > > Instead, measure the real elapsed time between each print_io() call. > We need to read the clock during every call, regardless of mode, > because the mode can change between updates. > > This patch also changes the iostat view's behavior during the first > update. During that first update, iostat has no prior data to use > when computing rates. Currently, the resulting output is "totals > since boot divided by naptime". Here's a concrete example: > > $ systat -d1 io 1 > DEVICE READ WRITE RTPS WTPS SEC > sd0 4544872K 7316640K 365102 687727 101.9 > sd1 0 0 0 0 0.0 > Totals 4544872K 7316640K 365102 687727 101.9 > $ systat -d1 io 2 > DEVICE READ WRITE RTPS WTPS SEC > sd0 2272436K 3658335K 182551 343866 50.9 > sd1 0 0 0 0 0.0 > Totals 2272436K 3658335K 182551 343866 50.9 > $ systat -d io 0.5 > DEVICE READ WRITE RTPS WTPS SEC > sd0 9089744K 14295M 730204 1376152 204.7 > sd1 0 0 0 0 0.0 > Totals 9089744K 14295M 730204 1376152 204.7 > > The second output is half the first (1 / 2). The third output is > twice the first (1 / 0.5). This is difficult to explain, let alone > document. The numbers are also meaningless. > > IMHO, if we're going to print something during that first update, it > makes more sense to unconditionally set etime to 1.0 and print the > totals. > > Thoughts? ok? Ping. Index: iostat.c =================================================================== RCS file: /cvs/src/usr.bin/systat/iostat.c,v diff -u -p -r1.50 iostat.c --- iostat.c 14 Aug 2021 14:22:26 -0000 1.50 +++ iostat.c 4 Apr 2024 19:15:29 -0000 @@ -166,13 +166,23 @@ read_io(void) void print_io(void) { + static struct timespec prev; + struct timespec elapsed, now; + static int first = 1; int n, count = 0; int curr; - if (state == BOOT) + clock_gettime(CLOCK_MONOTONIC, &now); + if (first) { + first = 0; etime = 1.0; - else - etime = naptime; + } else if (state == BOOT) { + etime = 1.0; + } else { + timespecsub(&now, &prev, &elapsed); + etime = elapsed.tv_sec + elapsed.tv_nsec / 1000000000.0; + } + prev = now; /* XXX engine internals: save and restore curr_line for bcache */ curr = curr_line;