diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-11 10:10:15 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-11 11:43:10 -0400 |
| commit | b09e0190acf88c7fe3b05e3c331e1b2ef5310896 (patch) | |
| tree | 260c82190298a9ee1b298679c6457c6b1735541a | |
| parent | e3174cfd2a1e28fff774681f00a0eef3d31da970 (diff) | |
perf hist: Adopt filter by dso and by thread methods from the newt browser
Those are really not specific to the newt code, can be used by other UI
frontends.
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/perf/builtin-report.c | 5 | ||||
| -rw-r--r-- | tools/perf/util/hist.c | 59 | ||||
| -rw-r--r-- | tools/perf/util/hist.h | 15 | ||||
| -rw-r--r-- | tools/perf/util/newt.c | 80 | ||||
| -rw-r--r-- | tools/perf/util/session.h | 15 |
5 files changed, 89 insertions, 85 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d7c75291e788..3d67d6bf22cf 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -301,10 +301,7 @@ static int __cmd_report(void) | |||
| 301 | hists__collapse_resort(hists); | 301 | hists__collapse_resort(hists); |
| 302 | hists__output_resort(hists); | 302 | hists__output_resort(hists); |
| 303 | if (use_browser) | 303 | if (use_browser) |
| 304 | perf_session__browse_hists(&hists->entries, | 304 | hists__browse(hists, help, input_name); |
| 305 | hists->nr_entries, | ||
| 306 | hists->stats.total, help, | ||
| 307 | input_name); | ||
| 308 | else { | 305 | else { |
| 309 | if (rb_first(&session->hists.entries) == | 306 | if (rb_first(&session->hists.entries) == |
| 310 | rb_last(&session->hists.entries)) | 307 | rb_last(&session->hists.entries)) |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e34fd248067d..baa55be64d9e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -784,3 +784,62 @@ print_entries: | |||
| 784 | 784 | ||
| 785 | return ret; | 785 | return ret; |
| 786 | } | 786 | } |
| 787 | |||
| 788 | enum hist_filter { | ||
| 789 | HIST_FILTER__DSO, | ||
| 790 | HIST_FILTER__THREAD, | ||
| 791 | }; | ||
| 792 | |||
| 793 | void hists__filter_by_dso(struct hists *self, const struct dso *dso) | ||
| 794 | { | ||
| 795 | struct rb_node *nd; | ||
| 796 | |||
| 797 | self->nr_entries = self->stats.total = 0; | ||
| 798 | self->max_sym_namelen = 0; | ||
| 799 | |||
| 800 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | ||
| 801 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | ||
| 802 | |||
| 803 | if (symbol_conf.exclude_other && !h->parent) | ||
| 804 | continue; | ||
| 805 | |||
| 806 | if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) { | ||
| 807 | h->filtered |= (1 << HIST_FILTER__DSO); | ||
| 808 | continue; | ||
| 809 | } | ||
| 810 | |||
| 811 | h->filtered &= ~(1 << HIST_FILTER__DSO); | ||
| 812 | if (!h->filtered) { | ||
| 813 | ++self->nr_entries; | ||
| 814 | self->stats.total += h->count; | ||
| 815 | if (h->ms.sym && | ||
| 816 | self->max_sym_namelen < h->ms.sym->namelen) | ||
| 817 | self->max_sym_namelen = h->ms.sym->namelen; | ||
| 818 | } | ||
| 819 | } | ||
| 820 | } | ||
| 821 | |||
| 822 | void hists__filter_by_thread(struct hists *self, const struct thread *thread) | ||
| 823 | { | ||
| 824 | struct rb_node *nd; | ||
| 825 | |||
| 826 | self->nr_entries = self->stats.total = 0; | ||
| 827 | self->max_sym_namelen = 0; | ||
| 828 | |||
| 829 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | ||
| 830 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | ||
| 831 | |||
| 832 | if (thread != NULL && h->thread != thread) { | ||
| 833 | h->filtered |= (1 << HIST_FILTER__THREAD); | ||
| 834 | continue; | ||
| 835 | } | ||
| 836 | h->filtered &= ~(1 << HIST_FILTER__THREAD); | ||
| 837 | if (!h->filtered) { | ||
| 838 | ++self->nr_entries; | ||
| 839 | self->stats.total += h->count; | ||
| 840 | if (h->ms.sym && | ||
| 841 | self->max_sym_namelen < h->ms.sym->namelen) | ||
| 842 | self->max_sym_namelen = h->ms.sym->namelen; | ||
| 843 | } | ||
| 844 | } | ||
| 845 | } | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 1b18d04195dc..1c5f93ac5ab7 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -44,4 +44,19 @@ void hists__output_resort(struct hists *self); | |||
| 44 | void hists__collapse_resort(struct hists *self); | 44 | void hists__collapse_resort(struct hists *self); |
| 45 | size_t hists__fprintf(struct hists *self, struct hists *pair, | 45 | size_t hists__fprintf(struct hists *self, struct hists *pair, |
| 46 | bool show_displacement, FILE *fp); | 46 | bool show_displacement, FILE *fp); |
| 47 | |||
| 48 | void hists__filter_by_dso(struct hists *self, const struct dso *dso); | ||
| 49 | void hists__filter_by_thread(struct hists *self, const struct thread *thread); | ||
| 50 | |||
| 51 | #ifdef NO_NEWT_SUPPORT | ||
| 52 | static inline int hists__browse(struct hists self __used, | ||
| 53 | const char *helpline __used, | ||
| 54 | const char *input_name __used) | ||
| 55 | { | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | #else | ||
| 59 | int hists__browse(struct hists *self, const char *helpline, | ||
| 60 | const char *input_name); | ||
| 61 | #endif | ||
| 47 | #endif /* __PERF_HIST_H */ | 62 | #endif /* __PERF_HIST_H */ |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index e283a6e6b6e0..638b519e72b8 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
| @@ -410,8 +410,8 @@ static void hist_browser__delete(struct hist_browser *self) | |||
| 410 | free(self); | 410 | free(self); |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | static int hist_browser__populate(struct hist_browser *self, struct rb_root *hists, | 413 | static int hist_browser__populate(struct hist_browser *self, struct hists *hists, |
| 414 | u64 nr_hists, u64 session_total, const char *title) | 414 | const char *title) |
| 415 | { | 415 | { |
| 416 | int max_len = 0, idx, cols, rows; | 416 | int max_len = 0, idx, cols, rows; |
| 417 | struct ui_progress *progress; | 417 | struct ui_progress *progress; |
| @@ -426,7 +426,7 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his | |||
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | snprintf(str, sizeof(str), "Samples: %Ld ", | 428 | snprintf(str, sizeof(str), "Samples: %Ld ", |
| 429 | session_total); | 429 | hists->stats.total); |
| 430 | newtDrawRootText(0, 0, str); | 430 | newtDrawRootText(0, 0, str); |
| 431 | 431 | ||
| 432 | newtGetScreenSize(NULL, &rows); | 432 | newtGetScreenSize(NULL, &rows); |
| @@ -442,24 +442,25 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his | |||
| 442 | newtComponentAddCallback(self->tree, hist_browser__selection, | 442 | newtComponentAddCallback(self->tree, hist_browser__selection, |
| 443 | &self->selection); | 443 | &self->selection); |
| 444 | 444 | ||
| 445 | progress = ui_progress__new("Adding entries to the browser...", nr_hists); | 445 | progress = ui_progress__new("Adding entries to the browser...", |
| 446 | hists->nr_entries); | ||
| 446 | if (progress == NULL) | 447 | if (progress == NULL) |
| 447 | return -1; | 448 | return -1; |
| 448 | 449 | ||
| 449 | idx = 0; | 450 | idx = 0; |
| 450 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { | 451 | for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { |
| 451 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 452 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
| 452 | int len; | 453 | int len; |
| 453 | 454 | ||
| 454 | if (h->filtered) | 455 | if (h->filtered) |
| 455 | continue; | 456 | continue; |
| 456 | 457 | ||
| 457 | len = hist_entry__append_browser(h, self->tree, session_total); | 458 | len = hist_entry__append_browser(h, self->tree, hists->stats.total); |
| 458 | if (len > max_len) | 459 | if (len > max_len) |
| 459 | max_len = len; | 460 | max_len = len; |
| 460 | if (symbol_conf.use_callchain) | 461 | if (symbol_conf.use_callchain) |
| 461 | hist_entry__append_callchain_browser(h, self->tree, | 462 | hist_entry__append_callchain_browser(h, self->tree, |
| 462 | session_total, idx++); | 463 | hists->stats.total, idx++); |
| 463 | ++curr_hist; | 464 | ++curr_hist; |
| 464 | if (curr_hist % 5) | 465 | if (curr_hist % 5) |
| 465 | ui_progress__update(progress, curr_hist); | 466 | ui_progress__update(progress, curr_hist); |
| @@ -490,57 +491,6 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his | |||
| 490 | return 0; | 491 | return 0; |
| 491 | } | 492 | } |
| 492 | 493 | ||
| 493 | enum hist_filter { | ||
| 494 | HIST_FILTER__DSO, | ||
| 495 | HIST_FILTER__THREAD, | ||
| 496 | }; | ||
| 497 | |||
| 498 | static u64 hists__filter_by_dso(struct rb_root *hists, const struct dso *dso, | ||
| 499 | u64 *session_total) | ||
| 500 | { | ||
| 501 | struct rb_node *nd; | ||
| 502 | u64 nr_hists = 0; | ||
| 503 | |||
| 504 | *session_total = 0; | ||
| 505 | |||
| 506 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { | ||
| 507 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | ||
| 508 | |||
| 509 | if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) { | ||
| 510 | h->filtered |= (1 << HIST_FILTER__DSO); | ||
| 511 | continue; | ||
| 512 | } | ||
| 513 | h->filtered &= ~(1 << HIST_FILTER__DSO); | ||
| 514 | ++nr_hists; | ||
| 515 | *session_total += h->count; | ||
| 516 | } | ||
| 517 | |||
| 518 | return nr_hists; | ||
| 519 | } | ||
| 520 | |||
| 521 | static u64 hists__filter_by_thread(struct rb_root *hists, const struct thread *thread, | ||
| 522 | u64 *session_total) | ||
| 523 | { | ||
| 524 | struct rb_node *nd; | ||
| 525 | u64 nr_hists = 0; | ||
| 526 | |||
| 527 | *session_total = 0; | ||
| 528 | |||
| 529 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { | ||
| 530 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | ||
| 531 | |||
| 532 | if (thread != NULL && h->thread != thread) { | ||
| 533 | h->filtered |= (1 << HIST_FILTER__THREAD); | ||
| 534 | continue; | ||
| 535 | } | ||
| 536 | h->filtered &= ~(1 << HIST_FILTER__THREAD); | ||
| 537 | ++nr_hists; | ||
| 538 | *session_total += h->count; | ||
| 539 | } | ||
| 540 | |||
| 541 | return nr_hists; | ||
| 542 | } | ||
| 543 | |||
| 544 | static struct thread *hist_browser__selected_thread(struct hist_browser *self) | 494 | static struct thread *hist_browser__selected_thread(struct hist_browser *self) |
| 545 | { | 495 | { |
| 546 | int *indexes; | 496 | int *indexes; |
| @@ -577,9 +527,7 @@ static int hist_browser__title(char *bf, size_t size, const char *input_name, | |||
| 577 | return printed ?: snprintf(bf, size, "Report: %s", input_name); | 527 | return printed ?: snprintf(bf, size, "Report: %s", input_name); |
| 578 | } | 528 | } |
| 579 | 529 | ||
| 580 | int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | 530 | int hists__browse(struct hists *self, const char *helpline, const char *input_name) |
| 581 | u64 session_total, const char *helpline, | ||
| 582 | const char *input_name) | ||
| 583 | { | 531 | { |
| 584 | struct hist_browser *browser = hist_browser__new(); | 532 | struct hist_browser *browser = hist_browser__new(); |
| 585 | const struct thread *thread_filter = NULL; | 533 | const struct thread *thread_filter = NULL; |
| @@ -595,7 +543,7 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | |||
| 595 | 543 | ||
| 596 | hist_browser__title(msg, sizeof(msg), input_name, | 544 | hist_browser__title(msg, sizeof(msg), input_name, |
| 597 | dso_filter, thread_filter); | 545 | dso_filter, thread_filter); |
| 598 | if (hist_browser__populate(browser, hists, nr_hists, session_total, msg) < 0) | 546 | if (hist_browser__populate(browser, self, msg) < 0) |
| 599 | goto out; | 547 | goto out; |
| 600 | 548 | ||
| 601 | while (1) { | 549 | while (1) { |
| @@ -672,10 +620,10 @@ do_annotate: | |||
| 672 | newtPushHelpLine(msg); | 620 | newtPushHelpLine(msg); |
| 673 | dso_filter = dso; | 621 | dso_filter = dso; |
| 674 | } | 622 | } |
| 675 | nr_hists = hists__filter_by_dso(hists, dso_filter, &session_total); | 623 | hists__filter_by_dso(self, dso_filter); |
| 676 | hist_browser__title(msg, sizeof(msg), input_name, | 624 | hist_browser__title(msg, sizeof(msg), input_name, |
| 677 | dso_filter, thread_filter); | 625 | dso_filter, thread_filter); |
| 678 | if (hist_browser__populate(browser, hists, nr_hists, session_total, msg) < 0) | 626 | if (hist_browser__populate(browser, self, msg) < 0) |
| 679 | goto out; | 627 | goto out; |
| 680 | } else if (choice == zoom_thread) { | 628 | } else if (choice == zoom_thread) { |
| 681 | if (thread_filter) { | 629 | if (thread_filter) { |
| @@ -689,10 +637,10 @@ do_annotate: | |||
| 689 | newtPushHelpLine(msg); | 637 | newtPushHelpLine(msg); |
| 690 | thread_filter = thread; | 638 | thread_filter = thread; |
| 691 | } | 639 | } |
| 692 | nr_hists = hists__filter_by_thread(hists, thread_filter, &session_total); | 640 | hists__filter_by_thread(self, thread_filter); |
| 693 | hist_browser__title(msg, sizeof(msg), input_name, | 641 | hist_browser__title(msg, sizeof(msg), input_name, |
| 694 | dso_filter, thread_filter); | 642 | dso_filter, thread_filter); |
| 695 | if (hist_browser__populate(browser, hists, nr_hists, session_total, msg) < 0) | 643 | if (hist_browser__populate(browser, self, msg) < 0) |
| 696 | goto out; | 644 | goto out; |
| 697 | } | 645 | } |
| 698 | } | 646 | } |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 46190f94b547..ce00fa6cdeda 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -102,21 +102,6 @@ int perf_session__create_kernel_maps(struct perf_session *self); | |||
| 102 | int do_read(int fd, void *buf, size_t size); | 102 | int do_read(int fd, void *buf, size_t size); |
| 103 | void perf_session__update_sample_type(struct perf_session *self); | 103 | void perf_session__update_sample_type(struct perf_session *self); |
| 104 | 104 | ||
| 105 | #ifdef NO_NEWT_SUPPORT | ||
| 106 | static inline int perf_session__browse_hists(struct rb_root *hists __used, | ||
| 107 | u64 nr_hists __used, | ||
| 108 | u64 session_total __used, | ||
| 109 | const char *helpline __used, | ||
| 110 | const char *input_name __used) | ||
| 111 | { | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | #else | ||
| 115 | int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | ||
| 116 | u64 session_total, const char *helpline, | ||
| 117 | const char *input_name); | ||
| 118 | #endif | ||
| 119 | |||
| 120 | static inline | 105 | static inline |
| 121 | struct machine *perf_session__find_host_machine(struct perf_session *self) | 106 | struct machine *perf_session__find_host_machine(struct perf_session *self) |
| 122 | { | 107 | { |
