On Thu, Jun 24, 2021 at 09:50:07PM -0500, Scott Cheloha wrote: > > [...] > > Stats for the clockintr subsystem are exposed via sysctl(2). If > you're interested in providing them you can compile and run the > program attached inline in my next mail. A snippet of the output from > across a suspend/resume is especially useful. > > [...]
Here's the program I mentioned. It prints clockintr stats once per second until you kill it (C-c works). You will need to do `make includes` first, as the patch in the prior mail added a new file to sys/dev and changed <sys/sysctl.h>. That or you can do a full `make build`. Assuming you put the inline file in clockintrstat.c, just build and run: $ cc -o clockintrstat clockintrstat.c $ ./clockintrstat Thanks, -Scott -- #include <sys/param.h> #include <sys/sysctl.h> #include <dev/clockintr.h> #include <err.h> #include <signal.h> #include <stdio.h> #include <string.h> #include <time.h> #include <unistd.h> volatile sig_atomic_t uninterrupted = 1; volatile sig_atomic_t need_header = 1; void alrm(int); void info(int); void quit(int); int main(void) { struct clockintr_stat diff, new, old; struct itimerval itv; struct timespec elapsed, now, then; uint64_t avg_lateness; int mib[] = { CTL_KERN, KERN_CLOCKINTR_STATS }; sigset_t empty; size_t len; int first, rows; memset(&diff, 0, sizeof(diff)); memset(&new, 0, sizeof(new)); memset(&old, 0, sizeof(old)); timespecclear(&now); timespecclear(&then); sigemptyset(&empty); len = sizeof(old); first = 1; signal(SIGALRM, alrm); signal(SIGINT, quit); signal(SIGINFO, info); itv.it_value.tv_sec = 1; itv.it_value.tv_usec = 0; itv.it_interval = itv.it_value; if (setitimer(ITIMER_REAL, &itv, NULL) == -1) err(1, "setitimer"); while (uninterrupted) { if (need_header) { need_header = 0; printf("%20s %15s %7s %7s %7s %10s\n", "uptime", "elapsed", "run", "early", "prompt", "avg-late"); if (!first) { sigsuspend(&empty); continue; } } old = new; if (sysctl(mib, nitems(mib), &new, &len, NULL, 0) == -1) err(1, "sysctl: KERN_CLOCKINTR_STATS"); then = now; clock_gettime(CLOCK_BOOTTIME, &now); if (first) { first = 0; sigsuspend(&empty); continue; } timespecsub(&now, &then, &elapsed); diff.cs_dispatch_early = new.cs_dispatch_early - old.cs_dispatch_early; diff.cs_dispatch_prompt = new.cs_dispatch_prompt - old.cs_dispatch_prompt; diff.cs_dispatch_lateness = new.cs_dispatch_lateness - old.cs_dispatch_lateness; diff.cs_events_run = new.cs_events_run - old.cs_events_run; if (diff.cs_dispatch_prompt == 0) avg_lateness = 0; else avg_lateness = diff.cs_dispatch_lateness / diff.cs_dispatch_prompt; printf("%10lld.%09ld %5lld.%09ld %7llu %7llu %7llu %10llu\n", (long long)now.tv_sec, now.tv_nsec, (long long)elapsed.tv_sec, elapsed.tv_nsec, diff.cs_events_run, diff.cs_dispatch_early, diff.cs_dispatch_prompt, avg_lateness); sigsuspend(&empty); } return 0; } void alrm(int signo) { } void info(int signo) { need_header = 1; } void quit(int signo) { uninterrupted = 0; }