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 | } |
