From fae71589595f22d2fe62f6bc7441f19fe8261467 Mon Sep 17 00:00:00 2001 From: Matt Macy Date: Mon, 4 Jun 2018 22:39:22 +0000 Subject: [PATCH] pmc stat: add debug option for intermediate state --- usr.sbin/pmc/cmd_pmc_stat.c | 60 ++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/usr.sbin/pmc/cmd_pmc_stat.c b/usr.sbin/pmc/cmd_pmc_stat.c index e32efb64a3d3..57ab6b9a54a2 100644 --- a/usr.sbin/pmc/cmd_pmc_stat.c +++ b/usr.sbin/pmc/cmd_pmc_stat.c @@ -244,11 +244,26 @@ pmc_stat_print_stat(struct rusage *ru) uint64_t ticks, value; int hz, i; - hz = getstathz(); - ticks = hz * (ru->ru_utime.tv_sec + ru->ru_stime.tv_sec) + - hz * (ru->ru_utime.tv_usec + ru->ru_stime.tv_usec) / 1000000; - if (clock_gettime(CLOCK_MONOTONIC, &after)) - err(1, "clock_gettime"); + if (ru) { + hz = getstathz(); + ticks = hz * (ru->ru_utime.tv_sec + ru->ru_stime.tv_sec) + + hz * (ru->ru_utime.tv_usec + ru->ru_stime.tv_usec) / 1000000; + if (clock_gettime(CLOCK_MONOTONIC, &after)) + err(1, "clock_gettime"); + /* + * If our round-off on the tick calculation still puts us at 0, + * then always assume at least one tick. + */ + if (ticks == 0) + ticks = 1; + fprintf(pmc_args.pa_printfile, "%16ld %s\t\t#\t%02.03f M/sec\n", + ru->ru_minflt, "page faults", ((double)ru->ru_minflt / (double)ticks) / hz); + fprintf(pmc_args.pa_printfile, "%16ld %s\t\t#\t%02.03f M/sec\n", + ru->ru_nvcsw, "voluntary csw", ((double)ru->ru_nvcsw / (double)ticks) / hz); + fprintf(pmc_args.pa_printfile, "%16ld %s\t#\t%02.03f M/sec\n", + ru->ru_nivcsw, "involuntary csw", ((double)ru->ru_nivcsw / (double)ticks) / hz); + } + bzero(&cvals, sizeof(cvals)); STAILQ_FOREACH(ev, &pmc_args.pa_events, ev_next) { if (pmc_read(ev->ev_pmcid, &value) < 0) @@ -259,19 +274,6 @@ pmc_stat_print_stat(struct rusage *ru) cvals[i] += value; } - /* - * If our round-off on the tick calculation still puts us at 0, - * then always assume at least one tick. - */ - if (ticks == 0) - ticks = 1; - fprintf(pmc_args.pa_printfile, "%16ld %s\t\t#\t%02.03f M/sec\n", - ru->ru_minflt, "page faults", ((double)ru->ru_minflt / (double)ticks) / hz); - fprintf(pmc_args.pa_printfile, "%16ld %s\t\t#\t%02.03f M/sec\n", - ru->ru_nvcsw, "voluntary csw", ((double)ru->ru_nvcsw / (double)ticks) / hz); - fprintf(pmc_args.pa_printfile, "%16ld %s\t#\t%02.03f M/sec\n", - ru->ru_nivcsw, "involuntary csw", ((double)ru->ru_nivcsw / (double)ticks) / hz); - fprintf(pmc_args.pa_printfile, "%16jd %s\n", (uintmax_t)cvals[CYCLES], stat_mode_names[CYCLES]); fprintf(pmc_args.pa_printfile, "%16jd %s\t\t#\t%01.03f inst/cycle\n", (uintmax_t)cvals[INST], stat_mode_names[INST], (double)cvals[INST] / cvals[CYCLES]); @@ -294,8 +296,8 @@ pmc_stat_print_stat(struct rusage *ru) fprintf(pmc_args.pa_printfile, "\t\t#\t%.03f%%\n", 100 * ((double)cvals[CACHE_MISS] / cvals[CACHE])); - - showtime(pmc_args.pa_printfile, &before_ts, &after, ru); + if (ru) + showtime(pmc_args.pa_printfile, &before_ts, &after, ru); } static struct option longopts[] = { @@ -313,15 +315,18 @@ pmc_stat_internal(int argc, char **argv, int system_mode) struct winsize ws; struct pmcstat_ev *ev; int c, option, runstate; - int waitstatus, ru_valid; + int waitstatus, ru_valid, do_debug; - ru_valid = 0; + do_debug = ru_valid = 0; r = event = NULL; - while ((option = getopt_long(argc, argv, "j:", longopts, NULL)) != -1) { + while ((option = getopt_long(argc, argv, "dj:", longopts, NULL)) != -1) { switch (option) { case 'j': r = event = strdup(optarg); break; + case 'd': + do_debug = 1; + break; case '?': default: usage(); @@ -342,6 +347,10 @@ pmc_stat_internal(int argc, char **argv, int system_mode) EV_SET(&kev, SIGIO, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); if (kevent(pmc_kq, &kev, 1, NULL, 0, NULL) < 0) err(EX_OSERR, "ERROR: Cannot register kevent for SIGIO"); + EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD, 0, 1000, NULL); + if (kevent(pmc_kq, &kev, 1, NULL, 0, NULL) < 0) + err(EX_OSERR, + "ERROR: Cannot register kevent for timer"); STAILQ_FOREACH(ev, &pmc_args.pa_events, ev_next) { if (pmc_allocate(ev->ev_spec, ev->ev_mode, @@ -415,7 +424,10 @@ pmc_stat_internal(int argc, char **argv, int system_mode) case EVFILT_READ: /* log file data is present */ break; - + case EVFILT_TIMER: + if (do_debug) + pmc_stat_print_stat(NULL); + break; case EVFILT_SIGNAL: if (kev.ident == SIGCHLD) { /*