diff options
author | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
commit | d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2 (patch) | |
tree | b04f4bd7cd887f50e7d98af35f46b9834ff86c80 /usr.sbin/pmcstat | |
parent | 3c8e37b1d04827f33c0c9a7594bd1b1ef7cdb3d3 (diff) | |
parent | 4fbde208c6460d576f64d6dc3cdc6cab085a4283 (diff) | |
download | FreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.zip FreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.tar.gz |
Merge head from 7/28
Diffstat (limited to 'usr.sbin/pmcstat')
-rw-r--r-- | usr.sbin/pmcstat/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/pmcstat/Makefile.depend | 1 | ||||
-rw-r--r-- | usr.sbin/pmcstat/pmcstat.8 | 12 | ||||
-rw-r--r-- | usr.sbin/pmcstat/pmcstat.c | 44 | ||||
-rw-r--r-- | usr.sbin/pmcstat/pmcstat.h | 4 | ||||
-rw-r--r-- | usr.sbin/pmcstat/pmcstat_log.c | 6 |
6 files changed, 59 insertions, 12 deletions
diff --git a/usr.sbin/pmcstat/Makefile b/usr.sbin/pmcstat/Makefile index b8c8081..78cde44 100644 --- a/usr.sbin/pmcstat/Makefile +++ b/usr.sbin/pmcstat/Makefile @@ -5,8 +5,8 @@ PROG= pmcstat MAN= pmcstat.8 -DPADD= ${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM} ${LIBNCURSES} -LDADD= -lelf -lkvm -lpmc -lm -lncurses +DPADD= ${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM} ${LIBNCURSESW} +LDADD= -lelf -lkvm -lpmc -lm -lncursesw SRCS= pmcstat.c pmcstat.h pmcstat_log.c \ pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c \ diff --git a/usr.sbin/pmcstat/Makefile.depend b/usr.sbin/pmcstat/Makefile.depend index 063d52f..f382224 100644 --- a/usr.sbin/pmcstat/Makefile.depend +++ b/usr.sbin/pmcstat/Makefile.depend @@ -14,7 +14,6 @@ DIRDEPS = \ lib/libkvm \ lib/libpmc \ lib/msun \ - lib/ncurses/ncurses \ lib/ncurses/ncursesw \ diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8 index 97a2f62..6662d43 100644 --- a/usr.sbin/pmcstat/pmcstat.8 +++ b/usr.sbin/pmcstat/pmcstat.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 29, 2014 +.Dd May 16, 2014 .Dt PMCSTAT 8 .Os .Sh NAME @@ -52,6 +52,7 @@ .Op Fl f Ar pluginopt .Op Fl g .Op Fl k Ar kerneldir +.Op Fl l Ar secs .Op Fl m Ar pathname .Op Fl n Ar rate .Op Fl o Ar outputfile @@ -274,6 +275,13 @@ This directory specifies where should look for the kernel and its modules. The default is .Pa /boot/kernel . +.It Fl l Ar secs +Set system-wide performance measurement duration for +.Ar secs +seconds. +The argument +.Ar secs +may be a fractional value. .It Fl m Ar pathname Print the sampled PCs with the name, the start and ending addresses of the function within they live. @@ -463,7 +471,7 @@ utility first appeared in It is .Ud .Sh AUTHORS -.An Joseph Koshy Aq jkoshy@FreeBSD.org +.An Joseph Koshy Aq Mt jkoshy@FreeBSD.org .Sh BUGS The .Nm diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c index ae93b93..a045706 100644 --- a/usr.sbin/pmcstat/pmcstat.c +++ b/usr.sbin/pmcstat/pmcstat.c @@ -509,6 +509,7 @@ pmcstat_show_usage(void) "\t -f spec\t pass \"spec\" to as plugin option\n" "\t -g\t\t produce gprof(1) compatible profiles\n" "\t -k dir\t\t set the path to the kernel\n" + "\t -l secs\t set duration time\n" "\t -m file\t print sampled PCs to \"file\"\n" "\t -n rate\t set sampling rate\n" "\t -o file\t send print output to \"file\"\n" @@ -551,6 +552,7 @@ main(int argc, char **argv) { cpuset_t cpumask; double interval; + double duration; int hcpu, option, npmc, ncpu; int c, check_driver_stats, current_sampling_count; int do_callchain, do_descendants, do_logproccsw, do_logprocexit; @@ -600,6 +602,7 @@ main(int argc, char **argv) args.pa_toptty = 0; args.pa_topcolor = 0; args.pa_mergepmc = 0; + args.pa_duration = 0.0; STAILQ_INIT(&args.pa_events); SLIST_INIT(&args.pa_targets); bzero(&ds_start, sizeof(ds_start)); @@ -618,7 +621,7 @@ main(int argc, char **argv) CPU_SET(hcpu, &cpumask); while ((option = getopt(argc, argv, - "CD:EF:G:M:NO:P:R:S:TWa:c:df:gk:m:n:o:p:qr:s:t:vw:z:")) != -1) + "CD:EF:G:M:NO:P:R:S:TWa:c:df:gk:l:m:n:o:p:qr:s:t:vw:z:")) != -1) switch (option) { case 'a': /* Annotate + callgraph */ args.pa_flags |= FLAG_DO_ANNOTATE; @@ -692,6 +695,15 @@ main(int argc, char **argv) args.pa_flags |= FLAG_HAS_KERNELPATH; break; + case 'l': /* time duration in seconds */ + duration = strtod(optarg, &end); + if (*end != '\0' || duration <= 0) + errx(EX_USAGE, "ERROR: Illegal duration time " + "value \"%s\".", optarg); + args.pa_flags |= FLAG_HAS_DURATION; + args.pa_duration = duration; + break; + case 'm': args.pa_flags |= FLAG_DO_ANNOTATE; args.pa_plugin = PMCSTAT_PL_ANNOTATE; @@ -922,6 +934,12 @@ main(int argc, char **argv) errx(EX_USAGE, "ERROR: options -O and -R are mutually exclusive."); + /* disallow -T and -l together */ + if ((args.pa_flags & FLAG_HAS_DURATION) && + (args.pa_flags & FLAG_DO_TOP)) + errx(EX_USAGE, "ERROR: options -T and -l are mutually " + "exclusive."); + /* -m option is allowed with -R only. */ if (args.pa_flags & FLAG_DO_ANNOTATE && args.pa_inputpath == NULL) errx(EX_USAGE, "ERROR: option %s requires an input file", @@ -1279,6 +1297,20 @@ main(int argc, char **argv) "ERROR: Cannot register kevent for timer"); } + /* + * Setup a duration timer if we have sampling mode PMCs and + * a duration time is set + */ + if ((args.pa_flags & FLAG_HAS_SAMPLING_PMCS) && + (args.pa_flags & FLAG_HAS_DURATION)) { + EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD, 0, + args.pa_duration * 1000, NULL); + + if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0) + err(EX_OSERR, "ERROR: Cannot register kevent for " + "time duration"); + } + /* attach PMCs to the target process, starting it if specified */ if (args.pa_flags & FLAG_HAS_COMMANDLINE) pmcstat_create_process(); @@ -1355,7 +1387,7 @@ main(int argc, char **argv) /* * loop till either the target process (if any) exits, or we - * are killed by a SIGINT. + * are killed by a SIGINT or we reached the time duration. */ runstate = PMCSTAT_RUNNING; do_print = do_read = 0; @@ -1422,7 +1454,13 @@ main(int argc, char **argv) break; - case EVFILT_TIMER: /* print out counting PMCs */ + case EVFILT_TIMER: + /* time duration reached, exit */ + if (args.pa_flags & FLAG_HAS_DURATION) { + runstate = PMCSTAT_FINISHED; + break; + } + /* print out counting PMCs */ if ((args.pa_flags & FLAG_DO_TOP) && pmc_flush_logfile() == 0) do_read = 1; diff --git a/usr.sbin/pmcstat/pmcstat.h b/usr.sbin/pmcstat/pmcstat.h index c8ec14d..29dfeb7 100644 --- a/usr.sbin/pmcstat/pmcstat.h +++ b/usr.sbin/pmcstat/pmcstat.h @@ -54,13 +54,14 @@ #define FLAG_DO_TOP 0x00010000 /* -T */ #define FLAG_DO_ANALYSIS 0x00020000 /* -g or -G or -m or -T */ #define FLAGS_HAS_CPUMASK 0x00040000 /* -c */ +#define FLAG_HAS_DURATION 0x00080000 /* -l secs */ #define DEFAULT_SAMPLE_COUNT 65536 #define DEFAULT_WAIT_INTERVAL 5.0 #define DEFAULT_DISPLAY_HEIGHT 256 /* file virtual height */ #define DEFAULT_DISPLAY_WIDTH 1024 /* file virtual width */ #define DEFAULT_BUFFER_SIZE 4096 -#define DEFAULT_CALLGRAPH_DEPTH 4 +#define DEFAULT_CALLGRAPH_DEPTH 16 #define PRINT_HEADER_PREFIX "# " #define READPIPEFD 0 @@ -149,6 +150,7 @@ struct pmcstat_args { int pa_toptty; /* output to tty or file */ int pa_topcolor; /* terminal support color */ int pa_mergepmc; /* merge PMC with same name */ + double pa_duration; /* time duration */ int pa_argc; char **pa_argv; STAILQ_HEAD(, pmcstat_ev) pa_events; diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c index f0e4939..40de320 100644 --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -307,10 +307,10 @@ pmcstat_stats_reset(int reset_global) static int pmcstat_string_compute_hash(const char *s) { - int hash; + unsigned hash; - for (hash = 0; *s; s++) - hash ^= *s; + for (hash = 2166136261; *s; s++) + hash = (hash ^ *s) * 16777619; return (hash & PMCSTAT_HASH_MASK); } |