diff options
Diffstat (limited to 'tools/perf/util/ui/browsers/hists.c')
-rw-r--r-- | tools/perf/util/ui/browsers/hists.c | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index 4663dcb2a19b..d0c94b459685 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "../browser.h" | 17 | #include "../browser.h" |
18 | #include "../helpline.h" | 18 | #include "../helpline.h" |
19 | #include "../util.h" | 19 | #include "../util.h" |
20 | #include "../ui.h" | ||
20 | #include "map.h" | 21 | #include "map.h" |
21 | 22 | ||
22 | struct hist_browser { | 23 | struct hist_browser { |
@@ -294,6 +295,15 @@ static void hist_browser__set_folding(struct hist_browser *self, bool unfold) | |||
294 | ui_browser__reset_index(&self->b); | 295 | ui_browser__reset_index(&self->b); |
295 | } | 296 | } |
296 | 297 | ||
298 | static void ui_browser__warn_lost_events(struct ui_browser *browser) | ||
299 | { | ||
300 | ui_browser__warning(browser, 4, | ||
301 | "Events are being lost, check IO/CPU overload!\n\n" | ||
302 | "You may want to run 'perf' using a RT scheduler policy:\n\n" | ||
303 | " perf top -r 80\n\n" | ||
304 | "Or reduce the sampling frequency."); | ||
305 | } | ||
306 | |||
297 | static int hist_browser__run(struct hist_browser *self, const char *ev_name, | 307 | static int hist_browser__run(struct hist_browser *self, const char *ev_name, |
298 | void(*timer)(void *arg), void *arg, int delay_secs) | 308 | void(*timer)(void *arg), void *arg, int delay_secs) |
299 | { | 309 | { |
@@ -314,12 +324,18 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name, | |||
314 | key = ui_browser__run(&self->b, delay_secs); | 324 | key = ui_browser__run(&self->b, delay_secs); |
315 | 325 | ||
316 | switch (key) { | 326 | switch (key) { |
317 | case -1: | 327 | case K_TIMER: |
318 | /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */ | ||
319 | timer(arg); | 328 | timer(arg); |
320 | ui_browser__update_nr_entries(&self->b, self->hists->nr_entries); | 329 | ui_browser__update_nr_entries(&self->b, self->hists->nr_entries); |
321 | hists__browser_title(self->hists, title, sizeof(title), | 330 | |
322 | ev_name); | 331 | if (self->hists->stats.nr_lost_warned != |
332 | self->hists->stats.nr_events[PERF_RECORD_LOST]) { | ||
333 | self->hists->stats.nr_lost_warned = | ||
334 | self->hists->stats.nr_events[PERF_RECORD_LOST]; | ||
335 | ui_browser__warn_lost_events(&self->b); | ||
336 | } | ||
337 | |||
338 | hists__browser_title(self->hists, title, sizeof(title), ev_name); | ||
323 | ui_browser__show_title(&self->b, title); | 339 | ui_browser__show_title(&self->b, title); |
324 | continue; | 340 | continue; |
325 | case 'D': { /* Debug */ | 341 | case 'D': { /* Debug */ |
@@ -883,7 +899,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
883 | goto out_free_stack; | 899 | goto out_free_stack; |
884 | case 'a': | 900 | case 'a': |
885 | if (!browser->has_symbols) { | 901 | if (!browser->has_symbols) { |
886 | ui__warning( | 902 | ui_browser__warning(&browser->b, delay_secs * 2, |
887 | "Annotation is only available for symbolic views, " | 903 | "Annotation is only available for symbolic views, " |
888 | "include \"sym\" in --sort to use it."); | 904 | "include \"sym\" in --sort to use it."); |
889 | continue; | 905 | continue; |
@@ -901,7 +917,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
901 | case K_F1: | 917 | case K_F1: |
902 | case 'h': | 918 | case 'h': |
903 | case '?': | 919 | case '?': |
904 | ui__help_window("h/?/F1 Show this window\n" | 920 | ui_browser__help_window(&browser->b, |
921 | "h/?/F1 Show this window\n" | ||
905 | "UP/DOWN/PGUP\n" | 922 | "UP/DOWN/PGUP\n" |
906 | "PGDN/SPACE Navigate\n" | 923 | "PGDN/SPACE Navigate\n" |
907 | "q/ESC/CTRL+C Exit browser\n\n" | 924 | "q/ESC/CTRL+C Exit browser\n\n" |
@@ -914,7 +931,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
914 | "C Collapse all callchains\n" | 931 | "C Collapse all callchains\n" |
915 | "E Expand all callchains\n" | 932 | "E Expand all callchains\n" |
916 | "d Zoom into current DSO\n" | 933 | "d Zoom into current DSO\n" |
917 | "t Zoom into current Thread\n"); | 934 | "t Zoom into current Thread"); |
918 | continue; | 935 | continue; |
919 | case K_ENTER: | 936 | case K_ENTER: |
920 | case K_RIGHT: | 937 | case K_RIGHT: |
@@ -940,7 +957,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
940 | } | 957 | } |
941 | case K_ESC: | 958 | case K_ESC: |
942 | if (!left_exits && | 959 | if (!left_exits && |
943 | !ui__dialog_yesno("Do you really want to exit?")) | 960 | !ui_browser__dialog_yesno(&browser->b, |
961 | "Do you really want to exit?")) | ||
944 | continue; | 962 | continue; |
945 | /* Fall thru */ | 963 | /* Fall thru */ |
946 | case 'q': | 964 | case 'q': |
@@ -993,6 +1011,7 @@ add_exit_option: | |||
993 | 1011 | ||
994 | if (choice == annotate) { | 1012 | if (choice == annotate) { |
995 | struct hist_entry *he; | 1013 | struct hist_entry *he; |
1014 | int err; | ||
996 | do_annotate: | 1015 | do_annotate: |
997 | he = hist_browser__selected_entry(browser); | 1016 | he = hist_browser__selected_entry(browser); |
998 | if (he == NULL) | 1017 | if (he == NULL) |
@@ -1001,10 +1020,12 @@ do_annotate: | |||
1001 | * Don't let this be freed, say, by hists__decay_entry. | 1020 | * Don't let this be freed, say, by hists__decay_entry. |
1002 | */ | 1021 | */ |
1003 | he->used = true; | 1022 | he->used = true; |
1004 | hist_entry__tui_annotate(he, evsel->idx, nr_events, | 1023 | err = hist_entry__tui_annotate(he, evsel->idx, nr_events, |
1005 | timer, arg, delay_secs); | 1024 | timer, arg, delay_secs); |
1006 | he->used = false; | 1025 | he->used = false; |
1007 | ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); | 1026 | ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); |
1027 | if (err) | ||
1028 | ui_browser__handle_resize(&browser->b); | ||
1008 | } else if (choice == browse_map) | 1029 | } else if (choice == browse_map) |
1009 | map__browse(browser->selection->map); | 1030 | map__browse(browser->selection->map); |
1010 | else if (choice == zoom_dso) { | 1031 | else if (choice == zoom_dso) { |
@@ -1056,6 +1077,7 @@ out: | |||
1056 | struct perf_evsel_menu { | 1077 | struct perf_evsel_menu { |
1057 | struct ui_browser b; | 1078 | struct ui_browser b; |
1058 | struct perf_evsel *selection; | 1079 | struct perf_evsel *selection; |
1080 | bool lost_events, lost_events_warned; | ||
1059 | }; | 1081 | }; |
1060 | 1082 | ||
1061 | static void perf_evsel_menu__write(struct ui_browser *browser, | 1083 | static void perf_evsel_menu__write(struct ui_browser *browser, |
@@ -1068,14 +1090,29 @@ static void perf_evsel_menu__write(struct ui_browser *browser, | |||
1068 | unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; | 1090 | unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; |
1069 | const char *ev_name = event_name(evsel); | 1091 | const char *ev_name = event_name(evsel); |
1070 | char bf[256], unit; | 1092 | char bf[256], unit; |
1093 | const char *warn = " "; | ||
1094 | size_t printed; | ||
1071 | 1095 | ||
1072 | ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : | 1096 | ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : |
1073 | HE_COLORSET_NORMAL); | 1097 | HE_COLORSET_NORMAL); |
1074 | 1098 | ||
1075 | nr_events = convert_unit(nr_events, &unit); | 1099 | nr_events = convert_unit(nr_events, &unit); |
1076 | snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events, | 1100 | printed = snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events, |
1077 | unit, unit == ' ' ? "" : " ", ev_name); | 1101 | unit, unit == ' ' ? "" : " ", ev_name); |
1078 | slsmg_write_nstring(bf, browser->width); | 1102 | slsmg_printf("%s", bf); |
1103 | |||
1104 | nr_events = evsel->hists.stats.nr_events[PERF_RECORD_LOST]; | ||
1105 | if (nr_events != 0) { | ||
1106 | menu->lost_events = true; | ||
1107 | if (!current_entry) | ||
1108 | ui_browser__set_color(browser, HE_COLORSET_TOP); | ||
1109 | nr_events = convert_unit(nr_events, &unit); | ||
1110 | snprintf(bf, sizeof(bf), ": %ld%c%schunks LOST!", nr_events, | ||
1111 | unit, unit == ' ' ? "" : " "); | ||
1112 | warn = bf; | ||
1113 | } | ||
1114 | |||
1115 | slsmg_write_nstring(warn, browser->width - printed); | ||
1079 | 1116 | ||
1080 | if (current_entry) | 1117 | if (current_entry) |
1081 | menu->selection = evsel; | 1118 | menu->selection = evsel; |
@@ -1100,6 +1137,11 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, | |||
1100 | switch (key) { | 1137 | switch (key) { |
1101 | case K_TIMER: | 1138 | case K_TIMER: |
1102 | timer(arg); | 1139 | timer(arg); |
1140 | |||
1141 | if (!menu->lost_events_warned && menu->lost_events) { | ||
1142 | ui_browser__warn_lost_events(&menu->b); | ||
1143 | menu->lost_events_warned = true; | ||
1144 | } | ||
1103 | continue; | 1145 | continue; |
1104 | case K_RIGHT: | 1146 | case K_RIGHT: |
1105 | case K_ENTER: | 1147 | case K_ENTER: |
@@ -1133,7 +1175,8 @@ browse_hists: | |||
1133 | pos = list_entry(pos->node.prev, struct perf_evsel, node); | 1175 | pos = list_entry(pos->node.prev, struct perf_evsel, node); |
1134 | goto browse_hists; | 1176 | goto browse_hists; |
1135 | case K_ESC: | 1177 | case K_ESC: |
1136 | if (!ui__dialog_yesno("Do you really want to exit?")) | 1178 | if (!ui_browser__dialog_yesno(&menu->b, |
1179 | "Do you really want to exit?")) | ||
1137 | continue; | 1180 | continue; |
1138 | /* Fall thru */ | 1181 | /* Fall thru */ |
1139 | case 'q': | 1182 | case 'q': |
@@ -1145,7 +1188,8 @@ browse_hists: | |||
1145 | case K_LEFT: | 1188 | case K_LEFT: |
1146 | continue; | 1189 | continue; |
1147 | case K_ESC: | 1190 | case K_ESC: |
1148 | if (!ui__dialog_yesno("Do you really want to exit?")) | 1191 | if (!ui_browser__dialog_yesno(&menu->b, |
1192 | "Do you really want to exit?")) | ||
1149 | continue; | 1193 | continue; |
1150 | /* Fall thru */ | 1194 | /* Fall thru */ |
1151 | case 'q': | 1195 | case 'q': |