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;
}

Reply via email to