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 <jchar...@versign.com>
  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;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to