Skip to content

Commit

Permalink
perf trace: Add support for tracing workload given by command line
Browse files Browse the repository at this point in the history
Now perf trace is able to trace specified workload by forking it like
perf record does.  And also finish the tracing if the workload quits or
gets SIGINT.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1349413336-26936-5-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Namhyung Kim authored and Arnaldo Carvalho de Melo committed Oct 5, 2012
1 parent ee76120 commit f15eb53
Showing 1 changed file with 36 additions and 7 deletions.
43 changes: 36 additions & 7 deletions tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ struct trace {
struct perf_record_opts opts;
};

static bool done = false;

static void sig_handler(int sig __maybe_unused)
{
done = true;
}

static int trace__read_syscall_info(struct trace *trace, int id)
{
char tp_name[128];
Expand Down Expand Up @@ -189,11 +196,12 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
return 0;
}

static int trace__run(struct trace *trace)
static int trace__run(struct trace *trace, int argc, const char **argv)
{
struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
struct perf_evsel *evsel;
int err = -1, i, nr_events = 0, before;
const bool forks = argc > 0;

if (evlist == NULL) {
printf("Not enough memory to run!\n");
Expand All @@ -214,6 +222,17 @@ static int trace__run(struct trace *trace)

perf_evlist__config_attrs(evlist, &trace->opts);

signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);

if (forks) {
err = perf_evlist__prepare_workload(evlist, &trace->opts, argv);
if (err < 0) {
printf("Couldn't run the workload!\n");
goto out_delete_evlist;
}
}

err = perf_evlist__open(evlist);
if (err < 0) {
printf("Couldn't create the events: %s\n", strerror(errno));
Expand All @@ -227,6 +246,10 @@ static int trace__run(struct trace *trace)
}

perf_evlist__enable(evlist);

if (forks)
perf_evlist__start_workload(evlist);

again:
before = nr_events;

Expand Down Expand Up @@ -272,8 +295,15 @@ static int trace__run(struct trace *trace)
}
}

if (nr_events == before)
if (nr_events == before) {
if (done)
goto out_delete_evlist;

poll(evlist->pollfd, evlist->nr_fds, -1);
}

if (done)
perf_evlist__disable(evlist);

goto again;

Expand All @@ -286,7 +316,8 @@ static int trace__run(struct trace *trace)
int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
{
const char * const trace_usage[] = {
"perf trace [<options>]",
"perf trace [<options>] [<command>]",
"perf trace [<options>] -- <command> [<options>]",
NULL
};
struct trace trace = {
Expand Down Expand Up @@ -326,8 +357,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
char bf[BUFSIZ];

argc = parse_options(argc, argv, trace_options, trace_usage, 0);
if (argc)
usage_with_options(trace_usage, trace_options);

err = perf_target__validate(&trace.opts.target);
if (err) {
Expand All @@ -343,8 +372,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
return err;
}

if (perf_target__none(&trace.opts.target))
if (!argc && perf_target__none(&trace.opts.target))
trace.opts.target.system_wide = true;

return trace__run(&trace);
return trace__run(&trace, argc, argv);
}

0 comments on commit f15eb53

Please sign in to comment.