aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-trace.c
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2012-10-05 01:02:16 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-10-05 11:51:27 -0400
commitf15eb531d351163f1ea697c2dd8f15b66b01d289 (patch)
tree460790a74a49cc7e64dca014cbd05a035a5dd16f /tools/perf/builtin-trace.c
parentee76120e2d13a2d4eb0cc88da8a8e7f7909cc276 (diff)
perf trace: Add support for tracing workload given by command line
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>
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r--tools/perf/builtin-trace.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index da1183fa105a..4e9320bf11e1 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -52,6 +52,13 @@ struct trace {
52 struct perf_record_opts opts; 52 struct perf_record_opts opts;
53}; 53};
54 54
55static bool done = false;
56
57static void sig_handler(int sig __maybe_unused)
58{
59 done = true;
60}
61
55static int trace__read_syscall_info(struct trace *trace, int id) 62static int trace__read_syscall_info(struct trace *trace, int id)
56{ 63{
57 char tp_name[128]; 64 char tp_name[128];
@@ -189,11 +196,12 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
189 return 0; 196 return 0;
190} 197}
191 198
192static int trace__run(struct trace *trace) 199static int trace__run(struct trace *trace, int argc, const char **argv)
193{ 200{
194 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 201 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
195 struct perf_evsel *evsel; 202 struct perf_evsel *evsel;
196 int err = -1, i, nr_events = 0, before; 203 int err = -1, i, nr_events = 0, before;
204 const bool forks = argc > 0;
197 205
198 if (evlist == NULL) { 206 if (evlist == NULL) {
199 printf("Not enough memory to run!\n"); 207 printf("Not enough memory to run!\n");
@@ -214,6 +222,17 @@ static int trace__run(struct trace *trace)
214 222
215 perf_evlist__config_attrs(evlist, &trace->opts); 223 perf_evlist__config_attrs(evlist, &trace->opts);
216 224
225 signal(SIGCHLD, sig_handler);
226 signal(SIGINT, sig_handler);
227
228 if (forks) {
229 err = perf_evlist__prepare_workload(evlist, &trace->opts, argv);
230 if (err < 0) {
231 printf("Couldn't run the workload!\n");
232 goto out_delete_evlist;
233 }
234 }
235
217 err = perf_evlist__open(evlist); 236 err = perf_evlist__open(evlist);
218 if (err < 0) { 237 if (err < 0) {
219 printf("Couldn't create the events: %s\n", strerror(errno)); 238 printf("Couldn't create the events: %s\n", strerror(errno));
@@ -227,6 +246,10 @@ static int trace__run(struct trace *trace)
227 } 246 }
228 247
229 perf_evlist__enable(evlist); 248 perf_evlist__enable(evlist);
249
250 if (forks)
251 perf_evlist__start_workload(evlist);
252
230again: 253again:
231 before = nr_events; 254 before = nr_events;
232 255
@@ -272,8 +295,15 @@ again:
272 } 295 }
273 } 296 }
274 297
275 if (nr_events == before) 298 if (nr_events == before) {
299 if (done)
300 goto out_delete_evlist;
301
276 poll(evlist->pollfd, evlist->nr_fds, -1); 302 poll(evlist->pollfd, evlist->nr_fds, -1);
303 }
304
305 if (done)
306 perf_evlist__disable(evlist);
277 307
278 goto again; 308 goto again;
279 309
@@ -286,7 +316,8 @@ out:
286int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) 316int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
287{ 317{
288 const char * const trace_usage[] = { 318 const char * const trace_usage[] = {
289 "perf trace [<options>]", 319 "perf trace [<options>] [<command>]",
320 "perf trace [<options>] -- <command> [<options>]",
290 NULL 321 NULL
291 }; 322 };
292 struct trace trace = { 323 struct trace trace = {
@@ -326,8 +357,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
326 char bf[BUFSIZ]; 357 char bf[BUFSIZ];
327 358
328 argc = parse_options(argc, argv, trace_options, trace_usage, 0); 359 argc = parse_options(argc, argv, trace_options, trace_usage, 0);
329 if (argc)
330 usage_with_options(trace_usage, trace_options);
331 360
332 err = perf_target__validate(&trace.opts.target); 361 err = perf_target__validate(&trace.opts.target);
333 if (err) { 362 if (err) {
@@ -343,8 +372,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
343 return err; 372 return err;
344 } 373 }
345 374
346 if (perf_target__none(&trace.opts.target)) 375 if (!argc && perf_target__none(&trace.opts.target))
347 trace.opts.target.system_wide = true; 376 trace.opts.target.system_wide = true;
348 377
349 return trace__run(&trace); 378 return trace__run(&trace, argc, argv);
350} 379}