Hi,
Using nanosleep(2) to print the stats periodically causes the period
to drift. If you use setitimer(2) it won't drift.
ok?
Index: kstat.c
===================================================================
RCS file: /cvs/src/usr.bin/kstat/kstat.c,v
retrieving revision 1.6
diff -u -p -r1.6 kstat.c
--- kstat.c 13 Aug 2020 12:37:16 -0000 1.6
+++ kstat.c 17 Sep 2020 23:24:36 -0000
@@ -15,6 +15,7 @@
*/
#include <ctype.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -27,6 +28,7 @@
#include <err.h>
#include <vis.h>
+#include <sys/time.h>
#include <sys/tree.h>
#include <sys/ioctl.h>
#include <sys/time.h>
@@ -104,6 +106,7 @@ kstat_cmp(const struct kstat_entry *ea,
RBT_PROTOTYPE(kstat_tree, kstat_entry, entry, kstat_cmp);
RBT_GENERATE(kstat_tree, kstat_entry, entry, kstat_cmp);
+static void handle_alrm(int);
static struct kstat_filter *
kstat_filter_parse(char *);
static int kstat_filter_entry(struct kstat_filters *,
@@ -130,20 +133,23 @@ main(int argc, char *argv[])
{
struct kstat_filters kfs = TAILQ_HEAD_INITIALIZER(kfs);
struct kstat_tree kt = RBT_INITIALIZER();
+ struct itimerval itv;
+ time_t interval;
unsigned int version;
+ sigset_t empty;
int fd;
const char *errstr;
int ch;
- struct timespec interval = { 0, 0 };
int i;
+ interval = 0;
+
while ((ch = getopt(argc, argv, "w:")) != -1) {
switch (ch) {
case 'w':
- interval.tv_sec = strtonum(optarg, 1, 100000000,
- &errstr);
+ interval = strtonum(optarg, 1, 100000000, &errstr);
if (errstr != NULL)
- errx(1, "wait %s: %s", optarg, errstr);
+ errx(1, "wait is %s: %s", optarg, errstr);
break;
default:
usage();
@@ -168,17 +174,31 @@ main(int argc, char *argv[])
kstat_list(&kt, fd, version, &kfs);
kstat_print(&kt);
- if (interval.tv_sec == 0)
+ if (interval == 0)
return (0);
- for (;;) {
- nanosleep(&interval, NULL);
+ signal(SIGALRM, handle_alrm);
+ sigemptyset(&empty);
+
+ itv.it_value.tv_sec = interval;
+ itv.it_value.tv_usec = 0;
+ itv.it_interval = itv.it_value;
+ if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
+ err(1, "setitimer");
+ for (;;) {
+ sigsuspend(&empty);
kstat_read(&kt, fd);
kstat_print(&kt);
}
return (0);
+}
+
+static void
+handle_alrm(int signo)
+{
+ return;
}
static struct kstat_filter *