diff options
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r-- | tools/perf/builtin-record.c | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ca2affc9233f..a1b99eeac3c0 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -42,6 +42,7 @@ static unsigned int mmap_pages = 128; | |||
42 | static unsigned int user_freq = UINT_MAX; | 42 | static unsigned int user_freq = UINT_MAX; |
43 | static int freq = 1000; | 43 | static int freq = 1000; |
44 | static int output; | 44 | static int output; |
45 | static int pipe_output = 0; | ||
45 | static const char *output_name = "perf.data"; | 46 | static const char *output_name = "perf.data"; |
46 | static int group = 0; | 47 | static int group = 0; |
47 | static unsigned int realtime_prio = 0; | 48 | static unsigned int realtime_prio = 0; |
@@ -109,6 +110,11 @@ static void mmap_write_tail(struct mmap_data *md, unsigned long tail) | |||
109 | pc->data_tail = tail; | 110 | pc->data_tail = tail; |
110 | } | 111 | } |
111 | 112 | ||
113 | static void advance_output(size_t size) | ||
114 | { | ||
115 | bytes_written += size; | ||
116 | } | ||
117 | |||
112 | static void write_output(void *buf, size_t size) | 118 | static void write_output(void *buf, size_t size) |
113 | { | 119 | { |
114 | while (size) { | 120 | while (size) { |
@@ -435,10 +441,19 @@ static int process_buildids(void) | |||
435 | 441 | ||
436 | static void atexit_header(void) | 442 | static void atexit_header(void) |
437 | { | 443 | { |
438 | session->header.data_size += bytes_written; | 444 | if (!pipe_output) { |
445 | session->header.data_size += bytes_written; | ||
439 | 446 | ||
440 | process_buildids(); | 447 | process_buildids(); |
441 | perf_header__write(&session->header, output, true); | 448 | perf_header__write(&session->header, output, true); |
449 | } else { | ||
450 | int err; | ||
451 | |||
452 | err = event__synthesize_build_ids(process_synthesized_event, | ||
453 | session); | ||
454 | if (err < 0) | ||
455 | pr_err("Couldn't synthesize build ids.\n"); | ||
456 | } | ||
442 | } | 457 | } |
443 | 458 | ||
444 | static int __cmd_record(int argc, const char **argv) | 459 | static int __cmd_record(int argc, const char **argv) |
@@ -464,7 +479,9 @@ static int __cmd_record(int argc, const char **argv) | |||
464 | exit(-1); | 479 | exit(-1); |
465 | } | 480 | } |
466 | 481 | ||
467 | if (!stat(output_name, &st) && st.st_size) { | 482 | if (!strcmp(output_name, "-")) |
483 | pipe_output = 1; | ||
484 | else if (!stat(output_name, &st) && st.st_size) { | ||
468 | if (write_mode == WRITE_FORCE) { | 485 | if (write_mode == WRITE_FORCE) { |
469 | char oldname[PATH_MAX]; | 486 | char oldname[PATH_MAX]; |
470 | snprintf(oldname, sizeof(oldname), "%s.old", | 487 | snprintf(oldname, sizeof(oldname), "%s.old", |
@@ -482,7 +499,10 @@ static int __cmd_record(int argc, const char **argv) | |||
482 | else | 499 | else |
483 | flags |= O_TRUNC; | 500 | flags |= O_TRUNC; |
484 | 501 | ||
485 | output = open(output_name, flags, S_IRUSR|S_IWUSR); | 502 | if (pipe_output) |
503 | output = STDOUT_FILENO; | ||
504 | else | ||
505 | output = open(output_name, flags, S_IRUSR | S_IWUSR); | ||
486 | if (output < 0) { | 506 | if (output < 0) { |
487 | perror("failed to create output file"); | 507 | perror("failed to create output file"); |
488 | exit(-1); | 508 | exit(-1); |
@@ -496,7 +516,7 @@ static int __cmd_record(int argc, const char **argv) | |||
496 | } | 516 | } |
497 | 517 | ||
498 | if (!file_new) { | 518 | if (!file_new) { |
499 | err = perf_header__read(&session->header, output); | 519 | err = perf_header__read(session, output); |
500 | if (err < 0) | 520 | if (err < 0) |
501 | return err; | 521 | return err; |
502 | } | 522 | } |
@@ -522,6 +542,8 @@ static int __cmd_record(int argc, const char **argv) | |||
522 | } | 542 | } |
523 | 543 | ||
524 | if (!child_pid) { | 544 | if (!child_pid) { |
545 | if (pipe_output) | ||
546 | dup2(2, 1); | ||
525 | close(child_ready_pipe[0]); | 547 | close(child_ready_pipe[0]); |
526 | close(go_pipe[1]); | 548 | close(go_pipe[1]); |
527 | fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); | 549 | fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); |
@@ -573,7 +595,11 @@ static int __cmd_record(int argc, const char **argv) | |||
573 | open_counters(cpumap[i]); | 595 | open_counters(cpumap[i]); |
574 | } | 596 | } |
575 | 597 | ||
576 | if (file_new) { | 598 | if (pipe_output) { |
599 | err = perf_header__write_pipe(output); | ||
600 | if (err < 0) | ||
601 | return err; | ||
602 | } else if (file_new) { | ||
577 | err = perf_header__write(&session->header, output, false); | 603 | err = perf_header__write(&session->header, output, false); |
578 | if (err < 0) | 604 | if (err < 0) |
579 | return err; | 605 | return err; |
@@ -581,6 +607,34 @@ static int __cmd_record(int argc, const char **argv) | |||
581 | 607 | ||
582 | post_processing_offset = lseek(output, 0, SEEK_CUR); | 608 | post_processing_offset = lseek(output, 0, SEEK_CUR); |
583 | 609 | ||
610 | if (pipe_output) { | ||
611 | err = event__synthesize_attrs(&session->header, | ||
612 | process_synthesized_event, | ||
613 | session); | ||
614 | if (err < 0) { | ||
615 | pr_err("Couldn't synthesize attrs.\n"); | ||
616 | return err; | ||
617 | } | ||
618 | |||
619 | err = event__synthesize_event_types(process_synthesized_event, | ||
620 | session); | ||
621 | if (err < 0) { | ||
622 | pr_err("Couldn't synthesize event_types.\n"); | ||
623 | return err; | ||
624 | } | ||
625 | |||
626 | err = event__synthesize_tracing_data(output, attrs, | ||
627 | nr_counters, | ||
628 | process_synthesized_event, | ||
629 | session); | ||
630 | if (err <= 0) { | ||
631 | pr_err("Couldn't record tracing data.\n"); | ||
632 | return err; | ||
633 | } | ||
634 | |||
635 | advance_output(err); | ||
636 | } | ||
637 | |||
584 | err = event__synthesize_kernel_mmap(process_synthesized_event, | 638 | err = event__synthesize_kernel_mmap(process_synthesized_event, |
585 | session, "_text"); | 639 | session, "_text"); |
586 | if (err < 0) | 640 | if (err < 0) |