aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-10-05 18:11:32 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-10-07 11:12:51 -0400
commit81cce8de9437be9234f651be1f03e596c1b1a79a (patch)
tree0837eb23c9d74b3d54999ffaead67317cc8ab4d5 /tools/perf
parent1980c2ebd7020d82c024b8c4046849b38e78e7da (diff)
perf browsers: Add live mode to the hists, annotate browsers
This allows passing a timer to be run periodically, which will update the hists tree that then gers refreshed on the screen, just like the Live mode (symbol entries, annotation) we already have in 'perf top --tui'. Will be used by the new hist_entry/hists based 'top' tool. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-2r44qd8oe4sagzcgoikl8qzc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-report.c7
-rw-r--r--tools/perf/util/annotate.h7
-rw-r--r--tools/perf/util/evlist.c6
-rw-r--r--tools/perf/util/evlist.h4
-rw-r--r--tools/perf/util/hist.h14
-rw-r--r--tools/perf/util/ui/browsers/annotate.c25
-rw-r--r--tools/perf/util/ui/browsers/hists.c105
-rw-r--r--tools/perf/util/ui/browsers/top.c2
9 files changed, 116 insertions, 56 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index cf68819f7453..39e3d382b2d8 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -137,7 +137,7 @@ find_next:
137 } 137 }
138 138
139 if (use_browser > 0) { 139 if (use_browser > 0) {
140 key = hist_entry__tui_annotate(he, evidx); 140 key = hist_entry__tui_annotate(he, evidx, NULL, NULL, 0);
141 switch (key) { 141 switch (key) {
142 case KEY_RIGHT: 142 case KEY_RIGHT:
143 next = rb_next(nd); 143 next = rb_next(nd);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c1cc7ab6f849..e7140c6289b8 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -327,9 +327,10 @@ static int __cmd_report(void)
327 goto out_delete; 327 goto out_delete;
328 } 328 }
329 329
330 if (use_browser > 0) 330 if (use_browser > 0) {
331 perf_evlist__tui_browse_hists(session->evlist, help); 331 perf_evlist__tui_browse_hists(session->evlist, help,
332 else 332 NULL, NULL, 0);
333 } else
333 perf_evlist__tty_browse_hists(session->evlist, help); 334 perf_evlist__tty_browse_hists(session->evlist, help);
334 335
335out_delete: 336out_delete:
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 6ede1286ee71..aafbc7e9a9ba 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -91,13 +91,16 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
91#ifdef NO_NEWT_SUPPORT 91#ifdef NO_NEWT_SUPPORT
92static inline int symbol__tui_annotate(struct symbol *sym __used, 92static inline int symbol__tui_annotate(struct symbol *sym __used,
93 struct map *map __used, 93 struct map *map __used,
94 int evidx __used, int refresh __used) 94 int evidx __used,
95 void(*timer)(void *arg) __used,
96 void *arg __used, int delay_secs __used)
95{ 97{
96 return 0; 98 return 0;
97} 99}
98#else 100#else
99int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, 101int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
100 int refresh); 102 void(*timer)(void *arg), void *arg,
103 int delay_secs);
101#endif 104#endif
102 105
103extern const char *disassembler_style; 106extern const char *disassembler_style;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 72e9f4886b6d..2f6bc89027da 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -533,3 +533,9 @@ bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
533 first = list_entry(evlist->entries.next, struct perf_evsel, node); 533 first = list_entry(evlist->entries.next, struct perf_evsel, node);
534 return first->attr.sample_id_all; 534 return first->attr.sample_id_all;
535} 535}
536
537void perf_evlist__set_selected(struct perf_evlist *evlist,
538 struct perf_evsel *evsel)
539{
540 evlist->selected = evsel;
541}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index f34915002745..6be71fc57794 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -25,6 +25,7 @@ struct perf_evlist {
25 struct pollfd *pollfd; 25 struct pollfd *pollfd;
26 struct thread_map *threads; 26 struct thread_map *threads;
27 struct cpu_map *cpus; 27 struct cpu_map *cpus;
28 struct perf_evsel *selected;
28}; 29};
29 30
30struct perf_evsel; 31struct perf_evsel;
@@ -56,6 +57,9 @@ void perf_evlist__munmap(struct perf_evlist *evlist);
56void perf_evlist__disable(struct perf_evlist *evlist); 57void perf_evlist__disable(struct perf_evlist *evlist);
57void perf_evlist__enable(struct perf_evlist *evlist); 58void perf_evlist__enable(struct perf_evlist *evlist);
58 59
60void perf_evlist__set_selected(struct perf_evlist *evlist,
61 struct perf_evsel *evsel);
62
59static inline void perf_evlist__set_maps(struct perf_evlist *evlist, 63static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
60 struct cpu_map *cpus, 64 struct cpu_map *cpus,
61 struct thread_map *threads) 65 struct thread_map *threads)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index d3f976cc7c56..424f9eb8310c 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -100,13 +100,16 @@ struct perf_evlist;
100#ifdef NO_NEWT_SUPPORT 100#ifdef NO_NEWT_SUPPORT
101static inline 101static inline
102int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __used, 102int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __used,
103 const char *help __used) 103 const char *help __used, void(*timer)(void *arg) __used, void *arg,
104 int refresh __used)
104{ 105{
105 return 0; 106 return 0;
106} 107}
107 108
108static inline int hist_entry__tui_annotate(struct hist_entry *self __used, 109static inline int hist_entry__tui_annotate(struct hist_entry *self __used,
109 int evidx __used) 110 int evidx __used,
111 void(*timer)(void *arg) __used,
112 void *arg __used, int delay_secs __used);
110{ 113{
111 return 0; 114 return 0;
112} 115}
@@ -114,12 +117,15 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self __used,
114#define KEY_RIGHT -2 117#define KEY_RIGHT -2
115#else 118#else
116#include <newt.h> 119#include <newt.h>
117int hist_entry__tui_annotate(struct hist_entry *self, int evidx); 120int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
121 void(*timer)(void *arg), void *arg, int delay_secs);
118 122
119#define KEY_LEFT NEWT_KEY_LEFT 123#define KEY_LEFT NEWT_KEY_LEFT
120#define KEY_RIGHT NEWT_KEY_RIGHT 124#define KEY_RIGHT NEWT_KEY_RIGHT
121 125
122int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help); 126int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
127 void(*timer)(void *arg), void *arg,
128 int refresh);
123#endif 129#endif
124 130
125unsigned int hists__sort_list_width(struct hists *self); 131unsigned int hists__sort_list_width(struct hists *self);
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c
index 0229723aceb3..76c1d083aa94 100644
--- a/tools/perf/util/ui/browsers/annotate.c
+++ b/tools/perf/util/ui/browsers/annotate.c
@@ -164,7 +164,8 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
164} 164}
165 165
166static int annotate_browser__run(struct annotate_browser *self, int evidx, 166static int annotate_browser__run(struct annotate_browser *self, int evidx,
167 int refresh) 167 void(*timer)(void *arg) __used, void *arg __used,
168 int delay_secs)
168{ 169{
169 struct rb_node *nd = NULL; 170 struct rb_node *nd = NULL;
170 struct symbol *sym = self->b.priv; 171 struct symbol *sym = self->b.priv;
@@ -189,13 +190,13 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
189 190
190 nd = self->curr_hot; 191 nd = self->curr_hot;
191 192
192 if (refresh != 0) 193 if (delay_secs != 0)
193 newtFormSetTimer(self->b.form, refresh); 194 newtFormSetTimer(self->b.form, delay_secs * 1000);
194 195
195 while (1) { 196 while (1) {
196 key = ui_browser__run(&self->b); 197 key = ui_browser__run(&self->b);
197 198
198 if (refresh != 0) { 199 if (delay_secs != 0) {
199 annotate_browser__calc_percent(self, evidx); 200 annotate_browser__calc_percent(self, evidx);
200 /* 201 /*
201 * Current line focus got out of the list of most active 202 * Current line focus got out of the list of most active
@@ -212,7 +213,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
212 * FIXME we need to check if it was 213 * FIXME we need to check if it was
213 * es.reason == NEWT_EXIT_TIMER 214 * es.reason == NEWT_EXIT_TIMER
214 */ 215 */
215 if (refresh != 0) 216 if (timer != NULL)
217 timer(arg);
218
219 if (delay_secs != 0)
216 symbol__annotate_decay_histogram(sym, evidx); 220 symbol__annotate_decay_histogram(sym, evidx);
217 continue; 221 continue;
218 case NEWT_KEY_TAB: 222 case NEWT_KEY_TAB:
@@ -246,13 +250,16 @@ out:
246 return key; 250 return key;
247} 251}
248 252
249int hist_entry__tui_annotate(struct hist_entry *he, int evidx) 253int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
254 void(*timer)(void *arg), void *arg, int delay_secs)
250{ 255{
251 return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, 0); 256 return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx,
257 timer, arg, delay_secs);
252} 258}
253 259
254int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, 260int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
255 int refresh) 261 void(*timer)(void *arg), void *arg,
262 int delay_secs)
256{ 263{
257 struct objdump_line *pos, *n; 264 struct objdump_line *pos, *n;
258 struct annotation *notes; 265 struct annotation *notes;
@@ -293,7 +300,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
293 300
294 browser.b.entries = &notes->src->source, 301 browser.b.entries = &notes->src->source,
295 browser.b.width += 18; /* Percentage */ 302 browser.b.width += 18; /* Percentage */
296 ret = annotate_browser__run(&browser, evidx, refresh); 303 ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs);
297 list_for_each_entry_safe(pos, n, &notes->src->source, node) { 304 list_for_each_entry_safe(pos, n, &notes->src->source, node) {
298 list_del(&pos->node); 305 list_del(&pos->node);
299 objdump_line__free(pos); 306 objdump_line__free(pos);
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c
index 5d767c622dfc..6244d19bd1f2 100644
--- a/tools/perf/util/ui/browsers/hists.c
+++ b/tools/perf/util/ui/browsers/hists.c
@@ -24,8 +24,14 @@ struct hist_browser {
24 struct hists *hists; 24 struct hists *hists;
25 struct hist_entry *he_selection; 25 struct hist_entry *he_selection;
26 struct map_symbol *selection; 26 struct map_symbol *selection;
27 const struct thread *thread_filter;
28 const struct dso *dso_filter;
27}; 29};
28 30
31static int hists__browser_title(struct hists *self, char *bf, size_t size,
32 const char *ev_name, const struct dso *dso,
33 const struct thread *thread);
34
29static void hist_browser__refresh_dimensions(struct hist_browser *self) 35static void hist_browser__refresh_dimensions(struct hist_browser *self)
30{ 36{
31 /* 3 == +/- toggle symbol before actual hist_entry rendering */ 37 /* 3 == +/- toggle symbol before actual hist_entry rendering */
@@ -290,9 +296,12 @@ static void hist_browser__set_folding(struct hist_browser *self, bool unfold)
290 ui_browser__reset_index(&self->b); 296 ui_browser__reset_index(&self->b);
291} 297}
292 298
293static int hist_browser__run(struct hist_browser *self, const char *title) 299static int hist_browser__run(struct hist_browser *self, const char *ev_name,
300 void(*timer)(void *arg), void *arg, int delay_secs)
294{ 301{
295 int key; 302 int key;
303 int delay_msecs = delay_secs * 1000;
304 char title[160];
296 int exit_keys[] = { 'a', '?', 'h', 'C', 'd', 'D', 'E', 't', 305 int exit_keys[] = { 'a', '?', 'h', 'C', 'd', 'D', 'E', 't',
297 NEWT_KEY_ENTER, NEWT_KEY_RIGHT, NEWT_KEY_LEFT, 306 NEWT_KEY_ENTER, NEWT_KEY_RIGHT, NEWT_KEY_LEFT,
298 NEWT_KEY_TAB, NEWT_KEY_UNTAB, 0, }; 307 NEWT_KEY_TAB, NEWT_KEY_UNTAB, 0, };
@@ -301,17 +310,30 @@ static int hist_browser__run(struct hist_browser *self, const char *title)
301 self->b.nr_entries = self->hists->nr_entries; 310 self->b.nr_entries = self->hists->nr_entries;
302 311
303 hist_browser__refresh_dimensions(self); 312 hist_browser__refresh_dimensions(self);
313 hists__browser_title(self->hists, title, sizeof(title), ev_name,
314 self->dso_filter, self->thread_filter);
304 315
305 if (ui_browser__show(&self->b, title, 316 if (ui_browser__show(&self->b, title,
306 "Press '?' for help on key bindings") < 0) 317 "Press '?' for help on key bindings") < 0)
307 return -1; 318 return -1;
308 319
320 if (timer != NULL)
321 newtFormSetTimer(self->b.form, delay_msecs);
322
309 ui_browser__add_exit_keys(&self->b, exit_keys); 323 ui_browser__add_exit_keys(&self->b, exit_keys);
310 324
311 while (1) { 325 while (1) {
312 key = ui_browser__run(&self->b); 326 key = ui_browser__run(&self->b);
313 327
314 switch (key) { 328 switch (key) {
329 case -1:
330 /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
331 timer(arg);
332 hists__browser_title(self->hists, title, sizeof(title),
333 ev_name, self->dso_filter,
334 self->thread_filter);
335 ui_browser__show_title(&self->b, title);
336 continue;
315 case 'D': { /* Debug */ 337 case 'D': { /* Debug */
316 static int seq; 338 static int seq;
317 struct hist_entry *h = rb_entry(self->b.top, 339 struct hist_entry *h = rb_entry(self->b.top,
@@ -805,14 +827,13 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size,
805 827
806static int perf_evsel__hists_browse(struct perf_evsel *evsel, 828static int perf_evsel__hists_browse(struct perf_evsel *evsel,
807 const char *helpline, const char *ev_name, 829 const char *helpline, const char *ev_name,
808 bool left_exits) 830 bool left_exits,
831 void(*timer)(void *arg), void *arg,
832 int delay_secs)
809{ 833{
810 struct hists *self = &evsel->hists; 834 struct hists *self = &evsel->hists;
811 struct hist_browser *browser = hist_browser__new(self); 835 struct hist_browser *browser = hist_browser__new(self);
812 struct pstack *fstack; 836 struct pstack *fstack;
813 const struct thread *thread_filter = NULL;
814 const struct dso *dso_filter = NULL;
815 char msg[160];
816 int key = -1; 837 int key = -1;
817 838
818 if (browser == NULL) 839 if (browser == NULL)
@@ -824,8 +845,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
824 845
825 ui_helpline__push(helpline); 846 ui_helpline__push(helpline);
826 847
827 hists__browser_title(self, msg, sizeof(msg), ev_name,
828 dso_filter, thread_filter);
829 while (1) { 848 while (1) {
830 const struct thread *thread = NULL; 849 const struct thread *thread = NULL;
831 const struct dso *dso = NULL; 850 const struct dso *dso = NULL;
@@ -834,7 +853,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
834 annotate = -2, zoom_dso = -2, zoom_thread = -2, 853 annotate = -2, zoom_dso = -2, zoom_thread = -2,
835 browse_map = -2; 854 browse_map = -2;
836 855
837 key = hist_browser__run(browser, msg); 856 key = hist_browser__run(browser, ev_name, timer, arg, delay_secs);
838 857
839 if (browser->he_selection != NULL) { 858 if (browser->he_selection != NULL) {
840 thread = hist_browser__selected_thread(browser); 859 thread = hist_browser__selected_thread(browser);
@@ -889,9 +908,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
889 continue; 908 continue;
890 } 909 }
891 top = pstack__pop(fstack); 910 top = pstack__pop(fstack);
892 if (top == &dso_filter) 911 if (top == &browser->dso_filter)
893 goto zoom_out_dso; 912 goto zoom_out_dso;
894 if (top == &thread_filter) 913 if (top == &browser->thread_filter)
895 goto zoom_out_thread; 914 goto zoom_out_thread;
896 continue; 915 continue;
897 } 916 }
@@ -913,14 +932,14 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
913 932
914 if (thread != NULL && 933 if (thread != NULL &&
915 asprintf(&options[nr_options], "Zoom %s %s(%d) thread", 934 asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
916 (thread_filter ? "out of" : "into"), 935 (browser->thread_filter ? "out of" : "into"),
917 (thread->comm_set ? thread->comm : ""), 936 (thread->comm_set ? thread->comm : ""),
918 thread->pid) > 0) 937 thread->pid) > 0)
919 zoom_thread = nr_options++; 938 zoom_thread = nr_options++;
920 939
921 if (dso != NULL && 940 if (dso != NULL &&
922 asprintf(&options[nr_options], "Zoom %s %s DSO", 941 asprintf(&options[nr_options], "Zoom %s %s DSO",
923 (dso_filter ? "out of" : "into"), 942 (browser->dso_filter ? "out of" : "into"),
924 (dso->kernel ? "the Kernel" : dso->short_name)) > 0) 943 (dso->kernel ? "the Kernel" : dso->short_name)) > 0)
925 zoom_dso = nr_options++; 944 zoom_dso = nr_options++;
926 945
@@ -949,45 +968,42 @@ do_annotate:
949 if (he == NULL) 968 if (he == NULL)
950 continue; 969 continue;
951 970
952 hist_entry__tui_annotate(he, evsel->idx); 971 hist_entry__tui_annotate(he, evsel->idx,
972 timer, arg, delay_secs);
953 } else if (choice == browse_map) 973 } else if (choice == browse_map)
954 map__browse(browser->selection->map); 974 map__browse(browser->selection->map);
955 else if (choice == zoom_dso) { 975 else if (choice == zoom_dso) {
956zoom_dso: 976zoom_dso:
957 if (dso_filter) { 977 if (browser->dso_filter) {
958 pstack__remove(fstack, &dso_filter); 978 pstack__remove(fstack, &browser->dso_filter);
959zoom_out_dso: 979zoom_out_dso:
960 ui_helpline__pop(); 980 ui_helpline__pop();
961 dso_filter = NULL; 981 browser->dso_filter = NULL;
962 } else { 982 } else {
963 if (dso == NULL) 983 if (dso == NULL)
964 continue; 984 continue;
965 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"", 985 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"",
966 dso->kernel ? "the Kernel" : dso->short_name); 986 dso->kernel ? "the Kernel" : dso->short_name);
967 dso_filter = dso; 987 browser->dso_filter = dso;
968 pstack__push(fstack, &dso_filter); 988 pstack__push(fstack, &browser->dso_filter);
969 } 989 }
970 hists__filter_by_dso(self, dso_filter); 990 hists__filter_by_dso(self, browser->dso_filter);
971 hists__browser_title(self, msg, sizeof(msg), ev_name,
972 dso_filter, thread_filter);
973 hist_browser__reset(browser); 991 hist_browser__reset(browser);
974 } else if (choice == zoom_thread) { 992 } else if (choice == zoom_thread) {
975zoom_thread: 993zoom_thread:
976 if (thread_filter) { 994 if (browser->thread_filter) {
977 pstack__remove(fstack, &thread_filter); 995 pstack__remove(fstack, &browser->thread_filter);
978zoom_out_thread: 996zoom_out_thread:
979 ui_helpline__pop(); 997 ui_helpline__pop();
980 thread_filter = NULL; 998 browser->thread_filter = NULL;
981 } else { 999 } else {
982 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"", 1000 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
983 thread->comm_set ? thread->comm : "", 1001 thread->comm_set ? thread->comm : "",
984 thread->pid); 1002 thread->pid);
985 thread_filter = thread; 1003 browser->thread_filter = thread;
986 pstack__push(fstack, &thread_filter); 1004 pstack__push(fstack, &browser->thread_filter);
987 } 1005 }
988 hists__filter_by_thread(self, thread_filter); 1006 hists__filter_by_thread(self, browser->thread_filter);
989 hists__browser_title(self, msg, sizeof(msg), ev_name,
990 dso_filter, thread_filter);
991 hist_browser__reset(browser); 1007 hist_browser__reset(browser);
992 } 1008 }
993 } 1009 }
@@ -1026,9 +1042,11 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
1026 menu->selection = evsel; 1042 menu->selection = evsel;
1027} 1043}
1028 1044
1029static int perf_evsel_menu__run(struct perf_evsel_menu *menu, const char *help) 1045static int perf_evsel_menu__run(struct perf_evsel_menu *menu, const char *help,
1046 void(*timer)(void *arg), void *arg, int delay_secs)
1030{ 1047{
1031 int exit_keys[] = { NEWT_KEY_ENTER, NEWT_KEY_RIGHT, 0, }; 1048 int exit_keys[] = { NEWT_KEY_ENTER, NEWT_KEY_RIGHT, 0, };
1049 int delay_msecs = delay_secs * 1000;
1032 struct perf_evlist *evlist = menu->b.priv; 1050 struct perf_evlist *evlist = menu->b.priv;
1033 struct perf_evsel *pos; 1051 struct perf_evsel *pos;
1034 const char *ev_name, *title = "Available samples"; 1052 const char *ev_name, *title = "Available samples";
@@ -1038,20 +1056,29 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, const char *help)
1038 "ESC: exit, ENTER|->: Browse histograms") < 0) 1056 "ESC: exit, ENTER|->: Browse histograms") < 0)
1039 return -1; 1057 return -1;
1040 1058
1059 if (timer != NULL)
1060 newtFormSetTimer(menu->b.form, delay_msecs);
1061
1041 ui_browser__add_exit_keys(&menu->b, exit_keys); 1062 ui_browser__add_exit_keys(&menu->b, exit_keys);
1042 1063
1043 while (1) { 1064 while (1) {
1044 key = ui_browser__run(&menu->b); 1065 key = ui_browser__run(&menu->b);
1045 1066
1046 switch (key) { 1067 switch (key) {
1068 case -1:
1069 /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
1070 timer(arg);
1071 continue;
1047 case NEWT_KEY_RIGHT: 1072 case NEWT_KEY_RIGHT:
1048 case NEWT_KEY_ENTER: 1073 case NEWT_KEY_ENTER:
1049 if (!menu->selection) 1074 if (!menu->selection)
1050 continue; 1075 continue;
1051 pos = menu->selection; 1076 pos = menu->selection;
1077 perf_evlist__set_selected(evlist, pos);
1052browse_hists: 1078browse_hists:
1053 ev_name = event_name(pos); 1079 ev_name = event_name(pos);
1054 key = perf_evsel__hists_browse(pos, help, ev_name, true); 1080 key = perf_evsel__hists_browse(pos, help, ev_name, true,
1081 timer, arg, delay_secs);
1055 ui_browser__show_title(&menu->b, title); 1082 ui_browser__show_title(&menu->b, title);
1056 break; 1083 break;
1057 case NEWT_KEY_LEFT: 1084 case NEWT_KEY_LEFT:
@@ -1091,7 +1118,9 @@ out:
1091} 1118}
1092 1119
1093static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, 1120static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1094 const char *help) 1121 const char *help,
1122 void(*timer)(void *arg), void *arg,
1123 int delay_secs)
1095{ 1124{
1096 struct perf_evsel *pos; 1125 struct perf_evsel *pos;
1097 struct perf_evsel_menu menu = { 1126 struct perf_evsel_menu menu = {
@@ -1121,18 +1150,22 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1121 pos->name = strdup(ev_name); 1150 pos->name = strdup(ev_name);
1122 } 1151 }
1123 1152
1124 return perf_evsel_menu__run(&menu, help); 1153 return perf_evsel_menu__run(&menu, help, timer, arg, delay_secs);
1125} 1154}
1126 1155
1127int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help) 1156int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
1157 void(*timer)(void *arg), void *arg,
1158 int delay_secs)
1128{ 1159{
1129 1160
1130 if (evlist->nr_entries == 1) { 1161 if (evlist->nr_entries == 1) {
1131 struct perf_evsel *first = list_entry(evlist->entries.next, 1162 struct perf_evsel *first = list_entry(evlist->entries.next,
1132 struct perf_evsel, node); 1163 struct perf_evsel, node);
1133 const char *ev_name = event_name(first); 1164 const char *ev_name = event_name(first);
1134 return perf_evsel__hists_browse(first, help, ev_name, false); 1165 return perf_evsel__hists_browse(first, help, ev_name, false,
1166 timer, arg, delay_secs);
1135 } 1167 }
1136 1168
1137 return __perf_evlist__tui_browse_hists(evlist, help); 1169 return __perf_evlist__tui_browse_hists(evlist, help,
1170 timer, arg, delay_secs);
1138} 1171}
diff --git a/tools/perf/util/ui/browsers/top.c b/tools/perf/util/ui/browsers/top.c
index 9b6b43b32ac8..d43875b2356f 100644
--- a/tools/perf/util/ui/browsers/top.c
+++ b/tools/perf/util/ui/browsers/top.c
@@ -142,7 +142,7 @@ static void perf_top_browser__annotate(struct perf_top_browser *browser)
142 142
143 pthread_mutex_unlock(&notes->lock); 143 pthread_mutex_unlock(&notes->lock);
144do_annotation: 144do_annotation:
145 symbol__tui_annotate(sym, syme->map, 0, top->delay_secs * 1000); 145 symbol__tui_annotate(sym, syme->map, 0, NULL, NULL, top->delay_secs * 1000);
146} 146}
147 147
148static void perf_top_browser__warn_lost(struct perf_top_browser *browser) 148static void perf_top_browser__warn_lost(struct perf_top_browser *browser)