diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-23 21:36:51 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-23 21:36:51 -0400 |
| commit | d67f088e084755bdceb4f15bc6e05e309db1eea7 (patch) | |
| tree | 6eaae7aed4f990233e73851053f2a36b32ce55b2 /tools | |
| parent | 44bf460649a9b91f291176097e9d7e846e8c001e (diff) | |
perf report: Support multiple events on the TUI
The hists__tty_browse_tree function was created with the loop to print
all events, and its equivalent, hists__tui_browse_tree, was created in a
similar fashion, where it is possible to switch among the multiple
events, if present, using TAB to go the next event, and shift+TAB
(UNTAB) to go to the previous.
The report TUI now shows as the window title the name of the event and a
leak was fixed wrt pstacks.
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: Stephane Eranian <eranian@google.com>
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 | 60 | ||||
| -rw-r--r-- | tools/perf/util/hist.h | 14 | ||||
| -rw-r--r-- | tools/perf/util/newt.c | 74 |
3 files changed, 108 insertions, 40 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index a7b8760e401c..359205782964 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -288,6 +288,38 @@ static size_t hists__fprintf_nr_sample_events(struct hists *self, | |||
| 288 | return ret + fprintf(fp, "\n#\n"); | 288 | return ret + fprintf(fp, "\n#\n"); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | static int hists__tty_browse_tree(struct rb_root *tree, const char *help) | ||
| 292 | { | ||
| 293 | struct rb_node *next = rb_first(tree); | ||
| 294 | |||
| 295 | while (next) { | ||
| 296 | struct hists *hists = rb_entry(next, struct hists, rb_node); | ||
| 297 | const char *evname = NULL; | ||
| 298 | |||
| 299 | if (rb_first(&hists->entries) != rb_last(&hists->entries)) | ||
| 300 | evname = __event_name(hists->type, hists->config); | ||
| 301 | |||
| 302 | hists__fprintf_nr_sample_events(hists, evname, stdout); | ||
| 303 | hists__fprintf(hists, NULL, false, stdout); | ||
| 304 | fprintf(stdout, "\n\n"); | ||
| 305 | next = rb_next(&hists->rb_node); | ||
| 306 | } | ||
| 307 | |||
| 308 | if (sort_order == default_sort_order && | ||
| 309 | parent_pattern == default_parent_pattern) { | ||
| 310 | fprintf(stdout, "#\n# (%s)\n#\n", help); | ||
| 311 | |||
| 312 | if (show_threads) { | ||
| 313 | bool style = !strcmp(pretty_printing_style, "raw"); | ||
| 314 | perf_read_values_display(stdout, &show_threads_values, | ||
| 315 | style); | ||
| 316 | perf_read_values_destroy(&show_threads_values); | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | return 0; | ||
| 321 | } | ||
| 322 | |||
| 291 | static int __cmd_report(void) | 323 | static int __cmd_report(void) |
| 292 | { | 324 | { |
| 293 | int ret = -EINVAL; | 325 | int ret = -EINVAL; |
| @@ -330,34 +362,14 @@ static int __cmd_report(void) | |||
| 330 | hists = rb_entry(next, struct hists, rb_node); | 362 | hists = rb_entry(next, struct hists, rb_node); |
| 331 | hists__collapse_resort(hists); | 363 | hists__collapse_resort(hists); |
| 332 | hists__output_resort(hists); | 364 | hists__output_resort(hists); |
| 333 | if (use_browser > 0) | ||
| 334 | hists__browse(hists, help, input_name); | ||
| 335 | else { | ||
| 336 | const char *evname = NULL; | ||
| 337 | if (rb_first(&session->hists.entries) != | ||
| 338 | rb_last(&session->hists.entries)) | ||
| 339 | evname = __event_name(hists->type, hists->config); | ||
| 340 | |||
| 341 | hists__fprintf_nr_sample_events(hists, evname, stdout); | ||
| 342 | |||
| 343 | hists__fprintf(hists, NULL, false, stdout); | ||
| 344 | fprintf(stdout, "\n\n"); | ||
| 345 | } | ||
| 346 | |||
| 347 | next = rb_next(&hists->rb_node); | 365 | next = rb_next(&hists->rb_node); |
| 348 | } | 366 | } |
| 349 | 367 | ||
| 350 | if (use_browser <= 0 && sort_order == default_sort_order && | 368 | if (use_browser > 0) |
| 351 | parent_pattern == default_parent_pattern) { | 369 | hists__tui_browse_tree(&session->hists_tree, help); |
| 352 | fprintf(stdout, "#\n# (%s)\n#\n", help); | 370 | else |
| 371 | hists__tty_browse_tree(&session->hists_tree, help); | ||
| 353 | 372 | ||
| 354 | if (show_threads) { | ||
| 355 | bool style = !strcmp(pretty_printing_style, "raw"); | ||
| 356 | perf_read_values_display(stdout, &show_threads_values, | ||
| 357 | style); | ||
| 358 | perf_read_values_destroy(&show_threads_values); | ||
| 359 | } | ||
| 360 | } | ||
| 361 | out_delete: | 373 | out_delete: |
| 362 | perf_session__delete(session); | 374 | perf_session__delete(session); |
| 363 | return ret; | 375 | return ret; |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 2d5203fedb20..83fa33a7b38b 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -98,10 +98,17 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread); | |||
| 98 | #ifdef NO_NEWT_SUPPORT | 98 | #ifdef NO_NEWT_SUPPORT |
| 99 | static inline int hists__browse(struct hists *self __used, | 99 | static inline int hists__browse(struct hists *self __used, |
| 100 | const char *helpline __used, | 100 | const char *helpline __used, |
| 101 | const char *input_name __used) | 101 | const char *ev_name __used) |
| 102 | { | 102 | { |
| 103 | return 0; | 103 | return 0; |
| 104 | } | 104 | } |
| 105 | |||
| 106 | static inline int hists__tui_browse_tree(struct rb_root *self __used, | ||
| 107 | const char *help __used) | ||
| 108 | { | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 105 | static inline int hist_entry__tui_annotate(struct hist_entry *self __used) | 112 | static inline int hist_entry__tui_annotate(struct hist_entry *self __used) |
| 106 | { | 113 | { |
| 107 | return 0; | 114 | return 0; |
| @@ -111,9 +118,12 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self __used) | |||
| 111 | #else | 118 | #else |
| 112 | #include <newt.h> | 119 | #include <newt.h> |
| 113 | int hists__browse(struct hists *self, const char *helpline, | 120 | int hists__browse(struct hists *self, const char *helpline, |
| 114 | const char *input_name); | 121 | const char *ev_name); |
| 115 | int hist_entry__tui_annotate(struct hist_entry *self); | 122 | int hist_entry__tui_annotate(struct hist_entry *self); |
| 123 | |||
| 116 | #define KEY_LEFT NEWT_KEY_LEFT | 124 | #define KEY_LEFT NEWT_KEY_LEFT |
| 117 | #define KEY_RIGHT NEWT_KEY_RIGHT | 125 | #define KEY_RIGHT NEWT_KEY_RIGHT |
| 126 | |||
| 127 | int hists__tui_browse_tree(struct rb_root *self, const char *help); | ||
| 118 | #endif | 128 | #endif |
| 119 | #endif /* __PERF_HIST_H */ | 129 | #endif /* __PERF_HIST_H */ |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index ffd04720b754..d54c540f49db 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
| @@ -842,6 +842,8 @@ static int hist_browser__populate(struct hist_browser *self, struct hists *hists | |||
| 842 | newtFormAddHotKey(self->form, 'h'); | 842 | newtFormAddHotKey(self->form, 'h'); |
| 843 | newtFormAddHotKey(self->form, NEWT_KEY_F1); | 843 | newtFormAddHotKey(self->form, NEWT_KEY_F1); |
| 844 | newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); | 844 | newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); |
| 845 | newtFormAddHotKey(self->form, NEWT_KEY_TAB); | ||
| 846 | newtFormAddHotKey(self->form, NEWT_KEY_UNTAB); | ||
| 845 | newtFormAddComponents(self->form, self->tree, NULL); | 847 | newtFormAddComponents(self->form, self->tree, NULL); |
| 846 | self->selection = newt__symbol_tree_get_current(self->tree); | 848 | self->selection = newt__symbol_tree_get_current(self->tree); |
| 847 | 849 | ||
| @@ -873,7 +875,7 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *self) | |||
| 873 | return he ? he->thread : NULL; | 875 | return he ? he->thread : NULL; |
| 874 | } | 876 | } |
| 875 | 877 | ||
| 876 | static int hist_browser__title(char *bf, size_t size, const char *input_name, | 878 | static int hist_browser__title(char *bf, size_t size, const char *ev_name, |
| 877 | const struct dso *dso, const struct thread *thread) | 879 | const struct dso *dso, const struct thread *thread) |
| 878 | { | 880 | { |
| 879 | int printed = 0; | 881 | int printed = 0; |
| @@ -887,18 +889,18 @@ static int hist_browser__title(char *bf, size_t size, const char *input_name, | |||
| 887 | printed += snprintf(bf + printed, size - printed, | 889 | printed += snprintf(bf + printed, size - printed, |
| 888 | "%sDSO: %s", thread ? " " : "", | 890 | "%sDSO: %s", thread ? " " : "", |
| 889 | dso->short_name); | 891 | dso->short_name); |
| 890 | return printed ?: snprintf(bf, size, "Report: %s", input_name); | 892 | return printed ?: snprintf(bf, size, "Event: %s", ev_name); |
| 891 | } | 893 | } |
| 892 | 894 | ||
| 893 | int hists__browse(struct hists *self, const char *helpline, const char *input_name) | 895 | int hists__browse(struct hists *self, const char *helpline, const char *ev_name) |
| 894 | { | 896 | { |
| 895 | struct hist_browser *browser = hist_browser__new(); | 897 | struct hist_browser *browser = hist_browser__new(); |
| 896 | struct pstack *fstack = pstack__new(2); | 898 | struct pstack *fstack; |
| 897 | const struct thread *thread_filter = NULL; | 899 | const struct thread *thread_filter = NULL; |
| 898 | const struct dso *dso_filter = NULL; | 900 | const struct dso *dso_filter = NULL; |
| 899 | struct newtExitStruct es; | 901 | struct newtExitStruct es; |
| 900 | char msg[160]; | 902 | char msg[160]; |
| 901 | int err = -1; | 903 | int key = -1; |
| 902 | 904 | ||
| 903 | if (browser == NULL) | 905 | if (browser == NULL) |
| 904 | return -1; | 906 | return -1; |
| @@ -909,7 +911,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na | |||
| 909 | 911 | ||
| 910 | ui_helpline__push(helpline); | 912 | ui_helpline__push(helpline); |
| 911 | 913 | ||
| 912 | |||
