aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/ui/browsers/hists.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/ui/browsers/hists.c')
-rw-r--r--tools/perf/util/ui/browsers/hists.c74
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
22struct hist_browser { 23struct 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
298static 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
297static int hist_browser__run(struct hist_browser *self, const char *ev_name, 307static 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;
996do_annotate: 1015do_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:
1056struct perf_evsel_menu { 1077struct 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
1061static void perf_evsel_menu__write(struct ui_browser *browser, 1083static 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':