1
0
mirror of https://github.com/openbsd/src.git synced 2024-12-22 07:27:59 -08:00

Rewrite bytes/sec calculation using fixed point math.

This makes signal handler safe on OpenBSD.

To avoid overflows the accuracy is scaled. Above 10 minutes run time
we only care about second accuracy. Between 1 seconds and 10 minutes
we use millisecond accuracy.

Below one second we use nanoseconds, but those numbers are probably
meaningless.

Signal handler problem pointed out by deraadt

OK deraadt, millert, tb
This commit is contained in:
florian 2024-07-12 19:11:25 +00:00
parent 75e21034e2
commit ba080721f3

View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.25 2024/07/12 14:30:27 deraadt Exp $ */
/* $OpenBSD: misc.c,v 1.26 2024/07/12 19:11:25 florian Exp $ */
/* $NetBSD: misc.c,v 1.4 1995/03/21 09:04:10 cgd Exp $ */
/*-
@ -51,16 +51,26 @@ sig_summary(int notused)
{
int save_errno = errno;
struct timespec elapsed, now;
double nanosecs;
unsigned long long bps, msec;
if (ddflags & C_NOINFO)
return;
clock_gettime(CLOCK_MONOTONIC, &now);
timespecsub(&now, &st.start, &elapsed);
nanosecs = ((double)elapsed.tv_sec * 1000000000) + elapsed.tv_nsec;
if (nanosecs == 0)
nanosecs = 1;
if (elapsed.tv_sec > 600)
bps = st.bytes / elapsed.tv_sec;
else if (elapsed.tv_sec > 0) {
/* will overflow at ~ 30 exabytes / second */
msec = elapsed.tv_sec * 1000 + elapsed.tv_nsec / 1000000;
if (msec == 0)
msec = 1;
bps = st.bytes * 1000 / msec;
} else if (elapsed.tv_nsec > 0)
bps = st.bytes * 1000000000 / elapsed.tv_nsec;
else
bps = st.bytes;
/* Be async safe: use dprintf(3). */
dprintf(STDERR_FILENO, "%zu+%zu records in\n%zu+%zu records out\n",
@ -77,9 +87,8 @@ sig_summary(int notused)
if (!(ddflags & C_NOXFER)) {
dprintf(STDERR_FILENO,
"%lld bytes transferred in %lld.%03ld secs "
"(%0.0f bytes/sec)\n", (long long)st.bytes,
(long long)elapsed.tv_sec, elapsed.tv_nsec / 1000000,
((double)st.bytes * 1000000000) / nanosecs);
"(%llu bytes/sec)\n", (long long)st.bytes,
(long long)elapsed.tv_sec, elapsed.tv_nsec / 1000000, bps);
}
errno = save_errno;
}