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 /tools | |
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>
Diffstat (limited to 'tools')
-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 | { |