diff options
Diffstat (limited to 'tools/perf/ui/browsers/hists.c')
| -rw-r--r-- | tools/perf/ui/browsers/hists.c | 324 |
1 files changed, 195 insertions, 129 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b72ee6822222..08fecbe28a52 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -29,8 +29,8 @@ #include "../../util/top.h" #include "../../util/thread.h" #include "../../util/block-info.h" +#include "../../util/util.h" #include "../../arch/common.h" -#include "../../perf.h" #include "../browsers/hists.h" #include "../helpline.h" @@ -38,6 +38,7 @@ #include "../ui.h" #include "map.h" #include "annotate.h" +#include "annotate-data.h" #include "srcline.h" #include "string2.h" #include "units.h" @@ -407,11 +408,6 @@ static bool hist_browser__selection_has_children(struct hist_browser *browser) return container_of(ms, struct callchain_list, ms)->has_children; } -static bool hist_browser__he_selection_unfolded(struct hist_browser *browser) -{ - return browser->he_selection ? browser->he_selection->unfolded : false; -} - static bool hist_browser__selection_unfolded(struct hist_browser *browser) { struct hist_entry *he = browser->he_selection; @@ -584,8 +580,8 @@ static int hierarchy_set_folding(struct hist_browser *hb, struct hist_entry *he, return n; } -static void __hist_entry__set_folding(struct hist_entry *he, - struct hist_browser *hb, bool unfold) +static void hist_entry__set_folding(struct hist_entry *he, + struct hist_browser *hb, bool unfold) { hist_entry__init_have_children(he); he->unfolded = unfold ? he->has_children : false; @@ -603,34 +599,12 @@ static void __hist_entry__set_folding(struct hist_entry *he, he->nr_rows = 0; } -static void hist_entry__set_folding(struct hist_entry *he, - struct hist_browser *browser, bool unfold) -{ - double percent; - - percent = hist_entry__get_percent_limit(he); - if (he->filtered || percent < browser->min_pcnt) - return; - - __hist_entry__set_folding(he, browser, unfold); - - if (!he->depth || unfold) - browser->nr_hierarchy_entries++; - if (he->leaf) - browser->nr_callchain_rows += he->nr_rows; - else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { - browser->nr_hierarchy_entries++; - he->has_no_entry = true; - he->nr_rows = 1; - } else - he->has_no_entry = false; -} - static void __hist_browser__set_folding(struct hist_browser *browser, bool unfold) { struct rb_node *nd; struct hist_entry *he; + double percent; nd = rb_first_cached(&browser->hists->entries); while (nd) { @@ -640,6 +614,21 @@ __hist_browser__set_folding(struct hist_browser *browser, bool unfold) nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD); hist_entry__set_folding(he, browser, unfold); + + percent = hist_entry__get_percent_limit(he); + if (he->filtered || percent < browser->min_pcnt) + continue; + + if (!he->depth || unfold) + browser->nr_hierarchy_entries++; + if (he->leaf) + browser->nr_callchain_rows += he->nr_rows; + else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { + browser->nr_hierarchy_entries++; + he->has_no_entry = true; + he->nr_rows = 1; + } else + he->has_no_entry = false; } } @@ -659,8 +648,10 @@ static void hist_browser__set_folding_selected(struct hist_browser *browser, boo if (!browser->he_selection) return; - hist_entry__set_folding(browser->he_selection, browser, unfold); - browser->b.nr_entries = hist_browser__nr_entries(browser); + if (unfold == browser->he_selection->unfolded) + return; + + hist_browser__toggle_fold(browser); } static void ui_browser__warn_lost_events(struct ui_browser *browser) @@ -732,8 +723,8 @@ static int hist_browser__handle_hotkey(struct hist_browser *browser, bool warn_l hist_browser__set_folding(browser, true); break; case 'e': - /* Expand the selected entry. */ - hist_browser__set_folding_selected(browser, !hist_browser__he_selection_unfolded(browser)); + /* Toggle expand/collapse the selected entry. */ + hist_browser__toggle_fold(browser); break; case 'H': browser->show_headers = !browser->show_headers; @@ -1235,7 +1226,7 @@ int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) return ret; } -#define __HPP_COLOR_PERCENT_FN(_type, _field) \ +#define __HPP_COLOR_PERCENT_FN(_type, _field, _fmttype) \ static u64 __hpp_get_##_field(struct hist_entry *he) \ { \ return he->stat._field; \ @@ -1247,10 +1238,10 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ struct hist_entry *he) \ { \ return hpp__fmt(fmt, hpp, he, __hpp_get_##_field, " %*.2f%%", \ - __hpp__slsmg_color_printf, true); \ + __hpp__slsmg_color_printf, _fmttype); \ } -#define __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ +#define __HPP_COLOR_ACC_PERCENT_FN(_type, _field, _fmttype) \ static u64 __hpp_get_acc_##_field(struct hist_entry *he) \ { \ return he->stat_acc->_field; \ @@ -1271,23 +1262,44 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ return ret; \ } \ return hpp__fmt(fmt, hpp, he, __hpp_get_acc_##_field, \ - " %*.2f%%", __hpp__slsmg_color_printf, true); \ + " %*.2f%%", __hpp__slsmg_color_printf, \ + _fmttype); \ } -__HPP_COLOR_PERCENT_FN(overhead, period) -__HPP_COLOR_PERCENT_FN(overhead_sys, period_sys) -__HPP_COLOR_PERCENT_FN(overhead_us, period_us) -__HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys) -__HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us) -__HPP_COLOR_ACC_PERCENT_FN(overhead_acc, period) +#define __HPP_COLOR_MEM_STAT_FN(_name, _type) \ +static int \ +hist_browser__hpp_color_mem_stat_##_name(struct perf_hpp_fmt *fmt, \ + struct perf_hpp *hpp, \ + struct hist_entry *he) \ +{ \ + return hpp__fmt_mem_stat(fmt, hpp, he, PERF_MEM_STAT_##_type, \ + " %5.1f%%", __hpp__slsmg_color_printf);\ +} + +__HPP_COLOR_PERCENT_FN(overhead, period, PERF_HPP_FMT_TYPE__PERCENT) +__HPP_COLOR_PERCENT_FN(latency, latency, PERF_HPP_FMT_TYPE__LATENCY) +__HPP_COLOR_PERCENT_FN(overhead_sys, period_sys, PERF_HPP_FMT_TYPE__PERCENT) +__HPP_COLOR_PERCENT_FN(overhead_us, period_us, PERF_HPP_FMT_TYPE__PERCENT) +__HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys, PERF_HPP_FMT_TYPE__PERCENT) +__HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us, PERF_HPP_FMT_TYPE__PERCENT) +__HPP_COLOR_ACC_PERCENT_FN(overhead_acc, period, PERF_HPP_FMT_TYPE__PERCENT) +__HPP_COLOR_ACC_PERCENT_FN(latency_acc, latency, PERF_HPP_FMT_TYPE__LATENCY) +__HPP_COLOR_MEM_STAT_FN(op, OP) +__HPP_COLOR_MEM_STAT_FN(cache, CACHE) +__HPP_COLOR_MEM_STAT_FN(memory, MEMORY) +__HPP_COLOR_MEM_STAT_FN(snoop, SNOOP) +__HPP_COLOR_MEM_STAT_FN(dtlb, DTLB) #undef __HPP_COLOR_PERCENT_FN #undef __HPP_COLOR_ACC_PERCENT_FN +#undef __HPP_COLOR_MEM_STAT_FN void hist_browser__init_hpp(void) { perf_hpp__format[PERF_HPP__OVERHEAD].color = hist_browser__hpp_color_overhead; + perf_hpp__format[PERF_HPP__LATENCY].color = + hist_browser__hpp_color_latency; perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color = hist_browser__hpp_color_overhead_sys; perf_hpp__format[PERF_HPP__OVERHEAD_US].color = @@ -1298,6 +1310,18 @@ void hist_browser__init_hpp(void) hist_browser__hpp_color_overhead_guest_us; perf_hpp__format[PERF_HPP__OVERHEAD_ACC].color = hist_browser__hpp_color_overhead_acc; + perf_hpp__format[PERF_HPP__LATENCY_ACC].color = + hist_browser__hpp_color_latency_acc; + perf_hpp__format[PERF_HPP__MEM_STAT_OP].color = + hist_browser__hpp_color_mem_stat_op; + perf_hpp__format[PERF_HPP__MEM_STAT_CACHE].color = + hist_browser__hpp_color_mem_stat_cache; + perf_hpp__format[PERF_HPP__MEM_STAT_MEMORY].color = + hist_browser__hpp_color_mem_stat_memory; + perf_hpp__format[PERF_HPP__MEM_STAT_SNOOP].color = + hist_browser__hpp_color_mem_stat_snoop; + perf_hpp__format[PERF_HPP__MEM_STAT_DTLB].color = + hist_browser__hpp_color_mem_stat_dtlb; res_sample_init(); } @@ -1688,7 +1712,8 @@ hists_browser__scnprintf_headers(struct hist_browser *browser, char *buf, return ret; } -static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *browser, char *buf, size_t size) +static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *browser, + char *buf, size_t size, int line) { struct hists *hists = browser->hists; struct perf_hpp dummy_hpp = { @@ -1714,7 +1739,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows if (column++ < browser->b.horiz_scroll) continue; - ret = fmt->header(fmt, &dummy_hpp, hists, 0, NULL); + ret = fmt->header(fmt, &dummy_hpp, hists, line, NULL); if (advance_hpp_check(&dummy_hpp, ret)) break; @@ -1725,6 +1750,9 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows first_node = false; } + if (line < hists->hpp_list->nr_header_lines - 1) + return ret; + if (!first_node) { ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, "%*s", indent * HIERARCHY_INDENT, ""); @@ -1755,7 +1783,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows } first_col = false; - ret = fmt->header(fmt, &dummy_hpp, hists, 0, NULL); + ret = fmt->header(fmt, &dummy_hpp, hists, line, NULL); dummy_hpp.buf[ret] = '\0'; start = strim(dummy_hpp.buf); @@ -1774,14 +1802,18 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows static void hists_browser__hierarchy_headers(struct hist_browser *browser) { + struct perf_hpp_list *hpp_list = browser->hists->hpp_list; char headers[1024]; + int line; - hists_browser__scnprintf_hierarchy_headers(browser, headers, - sizeof(headers)); + for (line = 0; line < hpp_list->nr_header_lines; line++) { + hists_browser__scnprintf_hierarchy_headers(browser, headers, + sizeof(headers), line); - ui_browser__gotorc(&browser->b, 0, 0); - ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); - ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); + ui_browser__gotorc_title(&browser->b, line, 0); + ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); + ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); + } } static void hists_browser__headers(struct hist_browser *browser) @@ -2260,8 +2292,7 @@ struct hist_browser *hist_browser__new(struct hists *hists) static struct hist_browser * perf_evsel_browser__new(struct evsel *evsel, struct hist_browser_timer *hbt, - struct perf_env *env, - struct annotation_options *annotation_opts) + struct perf_env *env) { struct hist_browser *browser = hist_browser__new(evsel__hists(evsel)); @@ -2269,7 +2300,6 @@ perf_evsel_browser__new(struct evsel *evsel, browser->hbt = hbt; browser->env = env; browser->title = hists_browser__scnprintf_title; - browser->annotation_opts = annotation_opts; } return browser; } @@ -2426,12 +2456,11 @@ close_file_and_continue: struct popup_action { unsigned long time; struct thread *thread; + int (*fn)(struct hist_browser *browser, struct popup_action *act); struct map_symbol ms; int socket; - struct evsel *evsel; enum rstype rstype; - int (*fn)(struct hist_browser *browser, struct popup_action *act); }; static int @@ -2442,8 +2471,8 @@ do_annotate(struct hist_browser *browser, struct popup_action *act) struct hist_entry *he; int err; - if (!browser->annotation_opts->objdump_path && - perf_env__lookup_objdump(browser->env, &browser->annotation_opts->objdump_path)) + if (!annotate_opts.objdump_path && + perf_env__lookup_objdump(browser->env, &annotate_opts.objdump_path)) return 0; notes = symbol__annotation(act->ms.sym); @@ -2455,9 +2484,8 @@ do_annotate(struct hist_browser *browser, struct popup_action *act) else evsel = hists_to_evsel(browser->hists); - err = map_symbol__tui_annotate(&act->ms, evsel, browser->hbt, - browser->annotation_opts); he = hist_browser__selected_entry(browser); + err = __hist_entry__tui_annotate(he, &act->ms, evsel, browser->hbt, NO_ADDR); /* * offer option to annotate the other branch source or target * (if they exists) when returning from annotate @@ -2487,19 +2515,20 @@ static struct symbol *symbol__new_unresolved(u64 addr, struct map *map) return NULL; } - dso__insert_symbol(map->dso, sym); + dso__insert_symbol(map__dso(map), sym); } return sym; } static int -add_annotate_opt(struct hist_browser *browser __maybe_unused, - struct popup_action *act, char **optstr, +add_annotate_opt(struct popup_action *act, char **optstr, struct map_symbol *ms, u64 addr) { - if (!ms->map || !ms->map->dso || ms->map->dso->annotate_warned) + struct dso *dso; + + if (!ms->map || (dso = map__dso(ms->map)) == NULL || dso__annotate_warned(dso)) return 0; if (!ms->sym) @@ -2517,6 +2546,30 @@ add_annotate_opt(struct hist_browser *browser __maybe_unused, } static int +do_annotate_type(struct hist_browser *browser, struct popup_action *act __maybe_unused) +{ + struct hist_entry *he = browser->he_selection; + + hist_entry__annotate_data_tui(he, hists_to_evsel(browser->hists), browser->hbt); + ui_browser__handle_resize(&browser->b); + return 0; +} + +static int +add_annotate_type_opt(struct popup_action *act, char **optstr, + struct hist_entry *he) +{ + if (he == NULL || he->mem_type == NULL || he->mem_type->histograms == NULL) + return 0; + + if (asprintf(optstr, "Annotate type %s", he->mem_type->self.type_name) < 0) + return 0; + + act->fn = do_annotate_type; + return 1; +} + +static int do_zoom_thread(struct hist_browser *browser, struct popup_action *act) { struct thread *thread = act->thread; @@ -2531,13 +2584,15 @@ do_zoom_thread(struct hist_browser *browser, struct popup_action *act) thread__zput(browser->hists->thread_filter); ui_helpline__pop(); } else { + const char *comm_set_str = + thread__comm_set(thread) ? thread__comm_str(thread) : ""; + if (hists__has(browser->hists, thread)) { ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s(%d) thread\"", - thread->comm_set ? thread__comm_str(thread) : "", - thread->tid); + comm_set_str, thread__tid(thread)); } else { ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s thread\"", - thread->comm_set ? thread__comm_str(thread) : ""); + comm_set_str); } browser->hists->thread_filter = thread__get(thread); @@ -2555,20 +2610,19 @@ add_thread_opt(struct hist_browser *browser, struct popup_action *act, char **optstr, struct thread *thread) { int ret; + const char *comm_set_str, *in_out; if ((!hists__has(browser->hists, thread) && !hists__has(browser->hists, comm)) || thread == NULL) return 0; + in_out = browser->hists->thread_filter ? "out of" : "into"; + comm_set_str = thread__comm_set(thread) ? thread__comm_str(thread) : ""; if (hists__has(browser->hists, thread)) { ret = asprintf(optstr, "Zoom %s %s(%d) thread", - browser->hists->thread_filter ? "out of" : "into", - thread->comm_set ? thread__comm_str(thread) : "", - thread->tid); + in_out, comm_set_str, thread__tid(thread)); } else { - ret = asprintf(optstr, "Zoom %s %s thread", - browser->hists->thread_filter ? "out of" : "into", - thread->comm_set ? thread__comm_str(thread) : ""); + ret = asprintf(optstr, "Zoom %s %s thread", in_out, comm_set_str); } if (ret < 0) return 0; @@ -2589,9 +2643,10 @@ static int hists_browser__zoom_map(struct hist_browser *browser, struct map *map browser->hists->dso_filter = NULL; ui_helpline__pop(); } else { + struct dso *dso = map__dso(map); ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name); - browser->hists->dso_filter = map->dso; + __map__is_kernel(map) ? "the Kernel" : dso__short_name(dso)); + browser->hists->dso_filter = dso; perf_hpp__set_elide(HISTC_DSO, true); pstack__push(browser->pstack, &browser->hists->dso_filter); } @@ -2616,7 +2671,7 @@ add_dso_opt(struct hist_browser *browser, struct popup_action *act, if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly into the kernel)", browser->hists->dso_filter ? "out of" : "into", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0) + __map__is_kernel(map) ? "the Kernel" : dso__short_name(map__dso(map))) < 0) return 0; act->ms.map = map; @@ -2670,7 +2725,7 @@ add_map_opt(struct hist_browser *browser, } static int -do_run_script(struct hist_browser *browser __maybe_unused, +do_run_script(struct hist_browser *browser, struct popup_action *act) { char *script_opt; @@ -2709,27 +2764,26 @@ do_run_script(struct hist_browser *browser __maybe_unused, n += snprintf(script_opt + n, len - n, " --time %s,%s", start, end); } - script_browse(script_opt, act->evsel); + script_browse(script_opt, hists_to_evsel(browser->hists)); free(script_opt); return 0; } static int -do_res_sample_script(struct hist_browser *browser __maybe_unused, +do_res_sample_script(struct hist_browser *browser, struct popup_action *act) { struct hist_entry *he; he = hist_browser__selected_entry(browser); - res_sample_browse(he->res_samples, he->num_res, act->evsel, act->rstype); + res_sample_browse(he->res_samples, he->num_res, hists_to_evsel(browser->hists), act->rstype); return 0; } static int -add_script_opt_2(struct hist_browser *browser __maybe_unused, - struct popup_action *act, char **optstr, +add_script_opt_2(struct popup_action *act, char **optstr, struct thread *thread, struct symbol *sym, - struct evsel *evsel, const char *tstr) + const char *tstr) { if (thread) { @@ -2747,7 +2801,6 @@ add_script_opt_2(struct hist_browser *browser __maybe_unused, act->thread = thread; act->ms.sym = sym; - act->evsel = evsel; act->fn = do_run_script; return 1; } @@ -2755,13 +2808,12 @@ add_script_opt_2(struct hist_browser *browser __maybe_unused, static int add_script_opt(struct hist_browser *browser, struct popup_action *act, char **optstr, - struct thread *thread, struct symbol *sym, - struct evsel *evsel) + struct thread *thread, struct symbol *sym) { int n, j; struct hist_entry *he; - n = add_script_opt_2(browser, act, optstr, thread, sym, evsel, ""); + n = add_script_opt_2(act, optstr, thread, sym, ""); he = hist_browser__selected_entry(browser); if (sort_order && strstr(sort_order, "time")) { @@ -2775,8 +2827,7 @@ add_script_opt(struct hist_browser *browser, j += sprintf(tstr + j, "-"); timestamp__scnprintf_usec(he->time + symbol_conf.time_quantum, tstr + j, sizeof tstr - j); - n += add_script_opt_2(browser, act, optstr, thread, sym, - evsel, tstr); + n += add_script_opt_2(act, optstr, thread, sym, tstr); act->time = he->time; } return n; @@ -2786,7 +2837,6 @@ static int add_res_sample_opt(struct hist_browser *browser __maybe_unused, struct popup_action *act, char **optstr, struct res_sample *res_sample, - struct evsel *evsel, enum rstype type) { if (!res_sample) @@ -2798,7 +2848,6 @@ add_res_sample_opt(struct hist_browser *browser __maybe_unused, return 0; act->fn = do_res_sample_script; - act->evsel = evsel; act->rstype = type; return 1; } @@ -2949,11 +2998,10 @@ next: static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *helpline, bool left_exits, struct hist_browser_timer *hbt, float min_pcnt, - struct perf_env *env, bool warn_lost_event, - struct annotation_options *annotation_opts) + struct perf_env *env, bool warn_lost_event) { struct hists *hists = evsel__hists(evsel); - struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env, annotation_opts); + struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env); struct branch_info *bi = NULL; #define MAX_OPTIONS 16 char *options[MAX_OPTIONS]; @@ -3010,6 +3058,7 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h /* reset abort key so that it can get Ctrl-C as a key */ SLang_reset_tty(); SLang_init_tty(0, 0, 0); + SLtty_set_suspend_state(true); if (min_pcnt) browser->min_pcnt = min_pcnt; @@ -3091,8 +3140,8 @@ do_hotkey: // key came straight from options ui__popup_menu() if (!browser->selection || !browser->selection->map || - !browser->selection->map->dso || - browser->selection->map->dso->annotate_warned) { + !map__dso(browser->selection->map) || + dso__annotate_warned(map__dso(browser->selection->map))) { continue; } @@ -3139,7 +3188,8 @@ do_hotkey: // key came straight from options ui__popup_menu() continue; case 'k': if (browser->selection != NULL) - hists_browser__zoom_map(browser, browser->selection->maps->machine->vmlinux_map); + hists_browser__zoom_map(browser, + maps__machine(browser->selection->maps)->vmlinux_map); continue; case 'V': verbose = (verbose + 1) % 4; @@ -3183,7 +3233,7 @@ do_hotkey: // key came straight from options ui__popup_menu() case 'i': /* env->arch is NULL for live-mode (i.e. perf top) */ if (env->arch) - tui__header_window(env); + tui__header_window(evsel__session(evsel)); continue; case 'F': symbol_conf.filter_relative ^= 1; @@ -3248,10 +3298,10 @@ do_hotkey: // key came straight from options ui__popup_menu() /* * No need to set actions->dso here since * it's just to remove the current filter. - * Ditto for thread below. */ do_zoom_dso(browser, actions); } else if (top == &browser->hists->thread_filter) { + actions->thread = thread; do_zoom_thread(browser, actions); } else if (top == &browser->hists->socket_filter) { do_zoom_socket(browser, actions); @@ -3282,6 +3332,8 @@ do_hotkey: // key came straight from options ui__popup_menu() /* Fall thru */ default: helpline = "Press '?' for help on key bindings"; + ui_browser__warn_unhandled_hotkey(&browser->b, key, delay_secs, + ", use 'h'/'?'/F1 to see actions"); continue; } @@ -3296,25 +3348,25 @@ do_hotkey: // key came straight from options ui__popup_menu() if (bi == NULL) goto skip_annotation; - nr_options += add_annotate_opt(browser, - &actions[nr_options], + nr_options += add_annotate_opt(&actions[nr_options], &options[nr_options], &bi->from.ms, bi->from.al_addr); if (bi->to.ms.sym != bi->from.ms.sym) - nr_options += add_annotate_opt(browser, - &actions[nr_options], + nr_options += add_annotate_opt(&actions[nr_options], &options[nr_options], &bi->to.ms, bi->to.al_addr); - } else { - nr_options += add_annotate_opt(browser, - &actions[nr_options], + } else if (browser->he_selection) { + nr_options += add_annotate_opt(&actions[nr_options], &options[nr_options], browser->selection, browser->he_selection->ip); } skip_annotation: + nr_options += add_annotate_type_opt(&actions[nr_options], + &options[nr_options], + browser->he_selection); nr_options += add_thread_opt(browser, &actions[nr_options], &options[nr_options], thread); nr_options += add_dso_opt(browser, &actions[nr_options], @@ -3336,7 +3388,7 @@ skip_annotation: nr_options += add_script_opt(browser, &actions[nr_options], &options[nr_options], - thread, NULL, evsel); + thread, NULL); } /* * Note that browser->selection != NULL @@ -3351,24 +3403,23 @@ skip_annotation: nr_options += add_script_opt(browser, &actions[nr_options], &options[nr_options], - NULL, browser->selection->sym, - evsel); + NULL, browser->selection->sym); } } nr_options += add_script_opt(browser, &actions[nr_options], - &options[nr_options], NULL, NULL, evsel); + &options[nr_options], NULL, NULL); nr_options += add_res_sample_opt(browser, &actions[nr_options], &options[nr_options], hist_browser__selected_res_sample(browser), - evsel, A_NORMAL); + A_NORMAL); nr_options += add_res_sample_opt(browser, &actions[nr_options], &options[nr_options], hist_browser__selected_res_sample(browser), - evsel, A_ASM); + A_ASM); nr_options += add_res_sample_opt(browser, &actions[nr_options], &options[nr_options], hist_browser__selected_res_sample(browser), - evsel, A_SOURCE); + A_SOURCE); nr_options += add_switch_opt(browser, &actions[nr_options], &options[nr_options]); skip_scripting: @@ -3403,7 +3454,6 @@ out: struct evsel_menu { struct ui_browser b; struct evsel *selection; - struct annotation_options *annotation_opts; bool lost_events, lost_events_warned; float min_pcnt; struct perf_env *env; @@ -3504,8 +3554,7 @@ browse_hists: hbt->timer(hbt->arg); key = evsel__hists_browse(pos, nr_events, help, true, hbt, menu->min_pcnt, menu->env, - warn_lost_event, - menu->annotation_opts); + warn_lost_event); ui_browser__show_title(&menu->b, title); switch (key) { case K_TAB: @@ -3540,6 +3589,7 @@ browse_hists: case CTRL('c'): goto out; default: + ui_browser__warn_unhandled_hotkey(&menu->b, key, delay_secs, NULL); continue; } } @@ -3562,7 +3612,7 @@ static bool filter_group_entries(struct ui_browser *browser __maybe_unused, static int __evlist__tui_browse_hists(struct evlist *evlist, int nr_entries, const char *help, struct hist_browser_timer *hbt, float min_pcnt, struct perf_env *env, - bool warn_lost_event, struct annotation_options *annotation_opts) + bool warn_lost_event) { struct evsel *pos; struct evsel_menu menu = { @@ -3577,7 +3627,6 @@ static int __evlist__tui_browse_hists(struct evlist *evlist, int nr_entries, con }, .min_pcnt = min_pcnt, .env = env, - .annotation_opts = annotation_opts, }; ui_helpline__push("Press ESC to exit"); @@ -3612,8 +3661,7 @@ static bool evlist__single_entry(struct evlist *evlist) } int evlist__tui_browse_hists(struct evlist *evlist, const char *help, struct hist_browser_timer *hbt, - float min_pcnt, struct perf_env *env, bool warn_lost_event, - struct annotation_options *annotation_opts) + float min_pcnt, struct perf_env *env, bool warn_lost_event) { int nr_entries = evlist->core.nr_entries; @@ -3622,7 +3670,7 @@ single_entry: { struct evsel *first = evlist__first(evlist); return evsel__hists_browse(first, nr_entries, help, false, hbt, min_pcnt, - env, warn_lost_event, annotation_opts); + env, warn_lost_event); } } @@ -3640,7 +3688,7 @@ single_entry: { } return __evlist__tui_browse_hists(evlist, nr_entries, help, hbt, min_pcnt, env, - warn_lost_event, annotation_opts); + warn_lost_event); } static int block_hists_browser__title(struct hist_browser *browser, char *bf, @@ -3659,15 +3707,16 @@ static int block_hists_browser__title(struct hist_browser *browser, char *bf, } int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel, - float min_percent, struct perf_env *env, - struct annotation_options *annotation_opts) + float min_percent, struct perf_env *env) { struct hists *hists = &bh->block_hists; struct hist_browser *browser; int key = -1; struct popup_action action; + char *br_cntr_text = NULL; static const char help[] = - " q Quit \n"; + " q/ESC Quit \n" + " B Branch counter abbr list (Optional)\n"; browser = hist_browser__new(hists); if (!browser) @@ -3677,19 +3726,23 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel, browser->title = block_hists_browser__title; browser->min_pcnt = min_percent; browser->env = env; - browser->annotation_opts = annotation_opts; /* reset abort key so that it can get Ctrl-C as a key */ SLang_reset_tty(); SLang_init_tty(0, 0, 0); + SLtty_set_suspend_state(true); memset(&action, 0, sizeof(action)); + if (!annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false)) + annotate_opts.show_br_cntr = true; + while (1) { key = hist_browser__run(browser, "? - help", true, 0); switch (key) { case 'q': + case K_ESC: goto out; case '?': ui_browser__help_window(&browser->b, help); @@ -3705,12 +3758,25 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel, action.ms.sym = browser->selection->sym; do_annotate(browser, &action); continue; + case 'B': + if (br_cntr_text) { + ui__question_window("Branch counter abbr list", + br_cntr_text, "Press any key...", 0); + } else { + ui__question_window("Branch counter abbr list", + "\n The branch counter is not available.\n", + "Press any key...", 0); + } + continue; default: - break; + ui_browser__warn_unhandled_hotkey(&browser->b, key, 0, + ", use '?' to see actions"); + continue; } } out: hist_browser__delete(browser); + free(br_cntr_text); return 0; } |
