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 <jcharbon@versign.com> MFC after: 2 weeks Relnotes: yes
This commit is contained in:
parent
0e1c93d3c1
commit
f767e17c96
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user