From owner-svn-src-head@FreeBSD.ORG Fri May 16 03:18:10 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 23B375FA; Fri, 16 May 2014 03:18:10 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 046B7200E; Fri, 16 May 2014 03:18:10 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4G3I9GS073020; Fri, 16 May 2014 03:18:09 GMT (envelope-from gnn@svn.freebsd.org) Received: (from gnn@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4G3I9Ov073017; Fri, 16 May 2014 03:18:09 GMT (envelope-from gnn@svn.freebsd.org) Message-Id: <201405160318.s4G3I9Ov073017@svn.freebsd.org> From: "George V. Neville-Neil" Date: Fri, 16 May 2014 03:18:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266209 - head/usr.sbin/pmcstat X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 May 2014 03:18:10 -0000 Author: gnn Date: Fri May 16 03:18:09 2014 New Revision: 266209 URL: http://svnweb.freebsd.org/changeset/base/266209 Log: Add a command line argument (-l) to end event collection after some number of seconds. The number of seconds may be a fraction. Submitted by: Julien Charbon MFC after: 2 weeks Relnotes: yes Modified: head/usr.sbin/pmcstat/pmcstat.8 head/usr.sbin/pmcstat/pmcstat.c head/usr.sbin/pmcstat/pmcstat.h Modified: head/usr.sbin/pmcstat/pmcstat.8 ============================================================================== --- head/usr.sbin/pmcstat/pmcstat.8 Fri May 16 03:05:53 2014 (r266208) +++ head/usr.sbin/pmcstat/pmcstat.8 Fri May 16 03:18:09 2014 (r266209) @@ -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. Modified: head/usr.sbin/pmcstat/pmcstat.c ============================================================================== --- head/usr.sbin/pmcstat/pmcstat.c Fri May 16 03:05:53 2014 (r266208) +++ head/usr.sbin/pmcstat/pmcstat.c Fri May 16 03:18:09 2014 (r266209) @@ -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; Modified: head/usr.sbin/pmcstat/pmcstat.h ============================================================================== --- head/usr.sbin/pmcstat/pmcstat.h Fri May 16 03:05:53 2014 (r266208) +++ head/usr.sbin/pmcstat/pmcstat.h Fri May 16 03:18:09 2014 (r266209) @@ -54,6 +54,7 @@ #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 @@ -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;