diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-12-14 10:10:39 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-12-14 10:57:18 -0500 |
commit | 4e4f06e4c8f17ea96f7dd76251cab99511026401 (patch) | |
tree | 18b7f83b664939be0a9bde8e43daf9db8ca7fccc /tools/perf/builtin-report.c | |
parent | b9bf089212d95746ce66482bcdbc7e77a0651088 (diff) |
perf session: Move the hist_entries rb tree to perf_session
As we'll need to sort multiple times for multiple perf sessions,
so that we can then do a diff.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260803439-16783-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r-- | tools/perf/builtin-report.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 9cbdcbc4cd56..854427f0e57e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -38,6 +38,7 @@ static char *dso_list_str, *comm_list_str, *sym_list_str, | |||
38 | static struct strlist *dso_list, *comm_list, *sym_list; | 38 | static struct strlist *dso_list, *comm_list, *sym_list; |
39 | 39 | ||
40 | static int force; | 40 | static int force; |
41 | static bool use_callchain; | ||
41 | 42 | ||
42 | static int show_nr_samples; | 43 | static int show_nr_samples; |
43 | 44 | ||
@@ -312,8 +313,9 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
312 | return ret; | 313 | return ret; |
313 | } | 314 | } |
314 | 315 | ||
315 | static size_t | 316 | static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self, |
316 | hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) | 317 | struct perf_session *session, |
318 | u64 total_samples) | ||
317 | { | 319 | { |
318 | struct sort_entry *se; | 320 | struct sort_entry *se; |
319 | size_t ret; | 321 | size_t ret; |
@@ -345,7 +347,7 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) | |||
345 | 347 | ||
346 | ret += fprintf(fp, "\n"); | 348 | ret += fprintf(fp, "\n"); |
347 | 349 | ||
348 | if (callchain) { | 350 | if (session->use_callchain) { |
349 | int left_margin = 0; | 351 | int left_margin = 0; |
350 | 352 | ||
351 | if (sort__first_dimension == SORT_COMM) { | 353 | if (sort__first_dimension == SORT_COMM) { |
@@ -422,7 +424,7 @@ static struct symbol **resolve_callchain(struct thread *thread, | |||
422 | struct symbol **syms = NULL; | 424 | struct symbol **syms = NULL; |
423 | unsigned int i; | 425 | unsigned int i; |
424 | 426 | ||
425 | if (callchain) { | 427 | if (session->use_callchain) { |
426 | syms = calloc(chain->nr, sizeof(*syms)); | 428 | syms = calloc(chain->nr, sizeof(*syms)); |
427 | if (!syms) { | 429 | if (!syms) { |
428 | fprintf(stderr, "Can't allocate memory for symbols\n"); | 430 | fprintf(stderr, "Can't allocate memory for symbols\n"); |
@@ -454,7 +456,7 @@ static struct symbol **resolve_callchain(struct thread *thread, | |||
454 | if (sort__has_parent && !*parent && | 456 | if (sort__has_parent && !*parent && |
455 | call__match(al.sym)) | 457 | call__match(al.sym)) |
456 | *parent = al.sym; | 458 | *parent = al.sym; |
457 | if (!callchain) | 459 | if (!session->use_callchain) |
458 | break; | 460 | break; |
459 | syms[i] = al.sym; | 461 | syms[i] = al.sym; |
460 | } | 462 | } |
@@ -467,25 +469,25 @@ static struct symbol **resolve_callchain(struct thread *thread, | |||
467 | * collect histogram counts | 469 | * collect histogram counts |
468 | */ | 470 | */ |
469 | 471 | ||
470 | static int hist_entry__add(struct addr_location *al, | 472 | static int perf_session__add_hist_entry(struct perf_session *self, |
471 | struct perf_session *session, | 473 | struct addr_location *al, |
472 | struct ip_callchain *chain, u64 count) | 474 | struct ip_callchain *chain, u64 count) |
473 | { | 475 | { |
474 | struct symbol **syms = NULL, *parent = NULL; | 476 | struct symbol **syms = NULL, *parent = NULL; |
475 | bool hit; | 477 | bool hit; |
476 | struct hist_entry *he; | 478 | struct hist_entry *he; |
477 | 479 | ||
478 | if ((sort__has_parent || callchain) && chain) | 480 | if ((sort__has_parent || self->use_callchain) && chain) |
479 | syms = resolve_callchain(al->thread, session, chain, &parent); | 481 | syms = resolve_callchain(al->thread, self, chain, &parent); |
480 | 482 | ||
481 | he = __hist_entry__add(al, parent, count, &hit); | 483 | he = __perf_session__add_hist_entry(self, al, parent, count, &hit); |
482 | if (he == NULL) | 484 | if (he == NULL) |
483 | return -ENOMEM; | 485 | return -ENOMEM; |
484 | 486 | ||
485 | if (hit) | 487 | if (hit) |
486 | he->count += count; | 488 | he->count += count; |
487 | 489 | ||
488 | if (callchain) { | 490 | if (self->use_callchain) { |
489 | if (!hit) | 491 | if (!hit) |
490 | callchain_init(&he->callchain); | 492 | callchain_init(&he->callchain); |
491 | append_chain(&he->callchain, chain, syms); | 493 | append_chain(&he->callchain, chain, syms); |
@@ -495,7 +497,8 @@ static int hist_entry__add(struct addr_location *al, | |||
495 | return 0; | 497 | return 0; |
496 | } | 498 | } |
497 | 499 | ||
498 | static size_t output__fprintf(FILE *fp, u64 total_samples) | 500 | static size_t perf_session__fprintf_hist_entries(struct perf_session *self, |
501 | u64 total_samples, FILE *fp) | ||
499 | { | 502 | { |
500 | struct hist_entry *pos; | 503 | struct hist_entry *pos; |
501 | struct sort_entry *se; | 504 | struct sort_entry *se; |
@@ -567,9 +570,9 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) | |||
567 | fprintf(fp, "#\n"); | 570 | fprintf(fp, "#\n"); |
568 | 571 | ||
569 | print_entries: | 572 | print_entries: |
570 | for (nd = rb_first(&hist); nd; nd = rb_next(nd)) { | 573 | for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { |
571 | pos = rb_entry(nd, struct hist_entry, rb_node); | 574 | pos = rb_entry(nd, struct hist_entry, rb_node); |
572 | ret += hist_entry__fprintf(fp, pos, total_samples); | 575 | ret += hist_entry__fprintf(fp, pos, self, total_samples); |
573 | } | 576 | } |
574 | 577 | ||
575 | if (sort_order == default_sort_order && | 578 | if (sort_order == default_sort_order && |
@@ -671,7 +674,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
671 | if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) | 674 | if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) |
672 | return 0; | 675 | return 0; |
673 | 676 | ||
674 | if (hist_entry__add(&al, session, data.callchain, data.period)) { | 677 | if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) { |
675 | pr_debug("problem incrementing symbol count, skipping event\n"); | 678 | pr_debug("problem incrementing symbol count, skipping event\n"); |
676 | return -1; | 679 | return -1; |
677 | } | 680 | } |
@@ -719,7 +722,7 @@ static int process_read_event(event_t *event, struct perf_session *session __use | |||
719 | return 0; | 722 | return 0; |
720 | } | 723 | } |
721 | 724 | ||
722 | static int sample_type_check(u64 type) | 725 | static int sample_type_check(u64 type, struct perf_session *session) |
723 | { | 726 | { |
724 | sample_type = type; | 727 | sample_type = type; |
725 | 728 | ||
@@ -730,14 +733,14 @@ static int sample_type_check(u64 type) | |||
730 | " perf record without -g?\n"); | 733 | " perf record without -g?\n"); |
731 | return -1; | 734 | return -1; |
732 | } | 735 | } |
733 | if (callchain) { | 736 | if (session->use_callchain) { |
734 | fprintf(stderr, "selected -g but no callchain data." | 737 | fprintf(stderr, "selected -g but no callchain data." |
735 | " Did you call perf record without" | 738 | " Did you call perf record without" |
736 | " -g?\n"); | 739 | " -g?\n"); |
737 | return -1; | 740 | return -1; |
738 | } | 741 | } |
739 | } else if (callchain_param.mode != CHAIN_NONE && !callchain) { | 742 | } else if (callchain_param.mode != CHAIN_NONE && !session->use_callchain) { |
740 | callchain = 1; | 743 | session->use_callchain = true; |
741 | if (register_callchain_param(&callchain_param) < 0) { | 744 | if (register_callchain_param(&callchain_param) < 0) { |
742 | fprintf(stderr, "Can't register callchain" | 745 | fprintf(stderr, "Can't register callchain" |
743 | " params\n"); | 746 | " params\n"); |
@@ -769,6 +772,8 @@ static int __cmd_report(void) | |||
769 | if (session == NULL) | 772 | if (session == NULL) |
770 | return -ENOMEM; | 773 | return -ENOMEM; |
771 | 774 | ||
775 | session->use_callchain = use_callchain; | ||
776 | |||
772 | if (show_threads) | 777 | if (show_threads) |
773 | perf_read_values_init(&show_threads_values); | 778 | perf_read_values_init(&show_threads_values); |
774 | 779 | ||
@@ -787,9 +792,9 @@ static int __cmd_report(void) | |||
787 | if (verbose > 2) | 792 | if (verbose > 2) |
788 | dsos__fprintf(stdout); | 793 | dsos__fprintf(stdout); |
789 | 794 | ||
790 | collapse__resort(); | 795 | perf_session__collapse_resort(session); |
791 | output__resort(event__stats.total); | 796 | perf_session__output_resort(session, event__stats.total); |
792 | output__fprintf(stdout, event__stats.total); | 797 | perf_session__fprintf_hist_entries(session, event__stats.total, stdout); |
793 | 798 | ||
794 | if (show_threads) | 799 | if (show_threads) |
795 | perf_read_values_destroy(&show_threads_values); | 800 | perf_read_values_destroy(&show_threads_values); |
@@ -805,7 +810,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, | |||
805 | char *tok; | 810 | char *tok; |
806 | char *endptr; | 811 | char *endptr; |
807 | 812 | ||
808 | callchain = 1; | 813 | use_callchain = true; |
809 | 814 | ||
810 | if (!arg) | 815 | if (!arg) |
811 | return 0; | 816 | return 0; |
@@ -826,7 +831,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, | |||
826 | 831 | ||
827 | else if (!strncmp(tok, "none", strlen(arg))) { | 832 | else if (!strncmp(tok, "none", strlen(arg))) { |
828 | callchain_param.mode = CHAIN_NONE; | 833 | callchain_param.mode = CHAIN_NONE; |
829 | callchain = 0; | 834 | use_callchain = true; |
830 | 835 | ||
831 | return 0; | 836 | return 0; |
832 | } | 837 | } |