aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-report.c7
-rw-r--r--tools/perf/util/hist.h16
-rw-r--r--tools/perf/util/ui/browsers/hists.c147
3 files changed, 140 insertions, 30 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 1c399eae5f7b..e9b5d513333a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -222,7 +222,8 @@ static size_t hists__fprintf_nr_sample_events(struct hists *self,
222 return ret + fprintf(fp, "\n#\n"); 222 return ret + fprintf(fp, "\n#\n");
223} 223}
224 224
225static int hists__tty_browse_tree(struct perf_evlist *evlist, const char *help) 225static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
226 const char *help)
226{ 227{
227 struct perf_evsel *pos; 228 struct perf_evsel *pos;
228 229
@@ -304,9 +305,9 @@ static int __cmd_report(void)
304 } 305 }
305 306
306 if (use_browser > 0) 307 if (use_browser > 0)
307 hists__tui_browse_tree(session->evlist, help); 308 perf_evlist__tui_browse_hists(session->evlist, help);
308 else 309 else
309 hists__tty_browse_tree(session->evlist, help); 310 perf_evlist__tty_browse_hists(session->evlist, help);
310 311
311out_delete: 312out_delete:
312 /* 313 /*
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 0d38b435827b..cb6858a2f9a3 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -87,15 +87,9 @@ bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len);
87struct perf_evlist; 87struct perf_evlist;
88 88
89#ifdef NO_NEWT_SUPPORT 89#ifdef NO_NEWT_SUPPORT
90static inline int hists__browse(struct hists *self __used, 90static inline
91 const char *helpline __used, 91int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __used,
92 const char *ev_name __used, int evidx __used) 92 const char *help __used)
93{
94 return 0;
95}
96
97static inline int hists__tui_browse_tree(struct perf_evlist *evlist __used,
98 const char *help __used)
99{ 93{
100 return 0; 94 return 0;
101} 95}
@@ -109,14 +103,12 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self __used,
109#define KEY_RIGHT -2 103#define KEY_RIGHT -2
110#else 104#else
111#include <newt.h> 105#include <newt.h>
112int hists__browse(struct hists *self, const char *helpline,
113 const char *ev_name, int evidx);
114int hist_entry__tui_annotate(struct hist_entry *self, int evidx); 106int hist_entry__tui_annotate(struct hist_entry *self, int evidx);
115 107
116#define KEY_LEFT NEWT_KEY_LEFT 108#define KEY_LEFT NEWT_KEY_LEFT
117#define KEY_RIGHT NEWT_KEY_RIGHT 109#define KEY_RIGHT NEWT_KEY_RIGHT
118 110
119int hists__tui_browse_tree(struct perf_evlist *evlist, const char *help); 111int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help);
120#endif 112#endif
121 113
122unsigned int hists__sort_list_width(struct hists *self); 114unsigned int hists__sort_list_width(struct hists *self);
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c
index f3af4fe5cdc4..798efdca3ead 100644
--- a/tools/perf/util/ui/browsers/hists.c
+++ b/tools/perf/util/ui/browsers/hists.c
@@ -803,9 +803,11 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size,
803 return printed; 803 return printed;
804} 804}
805 805
806int hists__browse(struct hists *self, const char *helpline, 806static int perf_evsel__hists_browse(struct perf_evsel *evsel,
807 const char *ev_name, int evidx) 807 const char *helpline, const char *ev_name,
808 bool left_exits)
808{ 809{
810 struct hists *self = &evsel->hists;
809 struct hist_browser *browser = hist_browser__new(self); 811 struct hist_browser *browser = hist_browser__new(self);
810 struct pstack *fstack; 812 struct pstack *fstack;
811 const struct thread *thread_filter = NULL; 813 const struct thread *thread_filter = NULL;
@@ -878,8 +880,14 @@ int hists__browse(struct hists *self, const char *helpline,
878 case NEWT_KEY_LEFT: { 880 case NEWT_KEY_LEFT: {
879 const void *top; 881 const void *top;
880 882
881 if (pstack__empty(fstack)) 883 if (pstack__empty(fstack)) {
884 /*
885 * Go back to the perf_evsel_menu__run or other user
886 */
887 if (left_exits)
888 goto out_free_stack;
882 continue; 889 continue;
890 }
883 top = pstack__pop(fstack); 891 top = pstack__pop(fstack);
884 if (top == &dso_filter) 892 if (top == &dso_filter)
885 goto zoom_out_dso; 893 goto zoom_out_dso;
@@ -888,7 +896,8 @@ int hists__browse(struct hists *self, const char *helpline,
888 continue; 896 continue;
889 } 897 }
890 case NEWT_KEY_ESCAPE: 898 case NEWT_KEY_ESCAPE:
891 if (!ui__dialog_yesno("Do you really want to exit?")) 899 if (!left_exits &&
900 !ui__dialog_yesno("Do you really want to exit?"))
892 continue; 901 continue;
893 /* Fall thru */ 902 /* Fall thru */
894 default: 903 default:
@@ -940,7 +949,7 @@ do_annotate:
940 if (he == NULL) 949 if (he == NULL)
941 continue; 950 continue;
942 951
943 hist_entry__tui_annotate(he, evidx); 952 hist_entry__tui_annotate(he, evsel->idx);
944 } else if (choice == browse_map) 953 } else if (choice == browse_map)
945 map__browse(browser->selection->map); 954 map__browse(browser->selection->map);
946 else if (choice == zoom_dso) { 955 else if (choice == zoom_dso) {
@@ -989,15 +998,71 @@ out:
989 return key; 998 return key;
990} 999}
991 1000
992int hists__tui_browse_tree(struct perf_evlist *evlist, const char *help) 1001struct perf_evsel_menu {
1002 struct ui_browser b;
1003 struct perf_evsel *selection;
1004};
1005
1006static void perf_evsel_menu__write(struct ui_browser *browser,
1007 void *entry, int row)
1008{
1009 struct perf_evsel_menu *menu = container_of(browser,
1010 struct perf_evsel_menu, b);
1011 struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
1012 bool current_entry = ui_browser__is_current_entry(browser, row);
1013 unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE];
1014 const char *ev_name = event_name(evsel);
1015 char bf[256], unit;
1016
1017 ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
1018 HE_COLORSET_NORMAL);
1019
1020 nr_events = convert_unit(nr_events, &unit);
1021 snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events,
1022 unit, unit == ' ' ? "" : " ", ev_name);
1023 slsmg_write_nstring(bf, browser->width);
1024
1025 if (current_entry)
1026 menu->selection = evsel;
1027}
1028
1029static int perf_evsel_menu__run(struct perf_evsel_menu *menu, const char *help)
993{ 1030{
1031 int exit_keys[] = { NEWT_KEY_ENTER, NEWT_KEY_RIGHT, 0, };
1032 struct perf_evlist *evlist = menu->b.priv;
994 struct perf_evsel *pos; 1033 struct perf_evsel *pos;
1034 const char *ev_name, *title = "Available samples";
1035 int key;
995 1036
996 pos = list_entry(evlist->entries.next, struct perf_evsel, node); 1037 if (ui_browser__show(&menu->b, title,
997 while (pos) { 1038 "ESC: exit, ENTER|->: Browse histograms") < 0)
998 struct hists *hists = &pos->hists; 1039 return -1;
999 const char *ev_name = event_name(pos); 1040
1000 int key = hists__browse(hists, help, ev_name, pos->idx); 1041 ui_browser__add_exit_keys(&menu->b, exit_keys);
1042
1043 while (1) {
1044 key = ui_browser__run(&menu->b);
1045
1046 switch (key) {
1047 case NEWT_KEY_RIGHT:
1048 case NEWT_KEY_ENTER:
1049 if (!menu->selection)
1050 continue;
1051 pos = menu->selection;
1052browse_hists:
1053 ev_name = event_name(pos);
1054 key = perf_evsel__hists_browse(pos, help, ev_name, true);
1055 ui_browser__show_title(&menu->b, title);
1056 break;
1057 case NEWT_KEY_LEFT:
1058 continue;
1059 case NEWT_KEY_ESCAPE:
1060 if (!ui__dialog_yesno("Do you really want to exit?"))
1061 continue;
1062 /* Fall thru */
1063 default:
1064 goto out;
1065 }
1001 1066
1002 switch (key) { 1067 switch (key) {
1003 case NEWT_KEY_TAB: 1068 case NEWT_KEY_TAB:
@@ -1005,17 +1070,69 @@ int hists__tui_browse_tree(struct perf_evlist *evlist, const char *help)
1005 pos = list_entry(evlist->entries.next, struct perf_evsel, node); 1070 pos = list_entry(evlist->entries.next, struct perf_evsel, node);
1006 else 1071 else
1007 pos = list_entry(pos->node.next, struct perf_evsel, node); 1072 pos = list_entry(pos->node.next, struct perf_evsel, node);
1008 break; 1073 goto browse_hists;
1009 case NEWT_KEY_UNTAB: 1074 case NEWT_KEY_UNTAB:
1010 if (pos->node.prev == &evlist->entries) 1075 if (pos->node.prev == &evlist->entries)
1011 pos = list_entry(evlist->entries.prev, struct perf_evsel, node); 1076 pos = list_entry(evlist->entries.prev, struct perf_evsel, node);
1012 else 1077 else
1013 pos = list_entry(pos->node.prev, struct perf_evsel, node); 1078 pos = list_entry(pos->node.prev, struct perf_evsel, node);
1014 break; 1079 goto browse_hists;
1080 case 'q':
1081 case CTRL('c'):
1082 goto out;
1015 default: 1083 default:
1016 return key; 1084 break;
1017 } 1085 }
1018 } 1086 }
1019 1087
1020 return 0; 1088out:
1089 ui_browser__hide(&menu->b);
1090 return key;
1091}
1092
1093static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1094 const char *help)
1095{
1096 struct perf_evsel *pos;
1097 struct perf_evsel_menu menu = {
1098 .b = {
1099 .entries = &evlist->entries,
1100 .refresh = ui_browser__list_head_refresh,
1101 .seek = ui_browser__list_head_seek,
1102 .write = perf_evsel_menu__write,
1103 .nr_entries = evlist->nr_entries,
1104 .priv = evlist,
1105 },
1106 };
1107
1108 ui_helpline__push("Press ESC to exit");
1109
1110 list_for_each_entry(pos, &evlist->entries, node) {
1111 const char *ev_name = event_name(pos);
1112 size_t line_len = strlen(ev_name) + 7;
1113
1114 if (menu.b.width < line_len)
1115 menu.b.width = line_len;
1116 /*
1117 * Cache the evsel name, tracepoints have a _high_ cost per
1118 * event_name() call.
1119 */
1120 if (pos->name == NULL)
1121 pos->name = strdup(ev_name);
1122 }
1123
1124 return perf_evsel_menu__run(&menu, help);
1125}
1126
1127int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help)
1128{
1129
1130 if (evlist->nr_entries == 1) {
1131 struct perf_evsel *first = list_entry(evlist->entries.next,
1132 struct perf_evsel, node);
1133 const char *ev_name = event_name(first);
1134 return perf_evsel__hists_browse(first, help, ev_name, false);
1135 }
1136
1137 return __perf_evlist__tui_browse_hists(evlist, help);
1021} 1138}