Download raw body.
systat(1): iostat: compute rates with elapsed time
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;
systat(1): iostat: compute rates with elapsed time