diff options
Diffstat (limited to 'tools/perf/ui/browsers/hists.c')
| -rw-r--r-- | tools/perf/ui/browsers/hists.c | 444 |
1 files changed, 241 insertions, 203 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 7ef36c36047..04a229aa5c0 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -17,6 +17,7 @@ #include "../util.h" #include "../ui.h" #include "map.h" +#include "annotate.h" struct hist_browser { struct ui_browser b; @@ -26,13 +27,35 @@ struct hist_browser { int print_seq; bool show_dso; float min_pcnt; - u64 nr_pcnt_entries; + u64 nr_non_filtered_entries; + u64 nr_callchain_rows; }; extern void hist_browser__init_hpp(void); static int hists__browser_title(struct hists *hists, char *bf, size_t size, const char *ev_name); +static void hist_browser__update_nr_entries(struct hist_browser *hb); + +static struct rb_node *hists__filter_entries(struct rb_node *nd, + float min_pcnt); + +static bool hist_browser__has_filter(struct hist_browser *hb) +{ + return hists__has_filter(hb->hists) || hb->min_pcnt; +} + +static u32 hist_browser__nr_entries(struct hist_browser *hb) +{ + u32 nr_entries; + + if (hist_browser__has_filter(hb)) + nr_entries = hb->nr_non_filtered_entries; + else + nr_entries = hb->hists->nr_entries; + + return nr_entries + hb->nr_callchain_rows; +} static void hist_browser__refresh_dimensions(struct hist_browser *browser) { @@ -43,7 +66,14 @@ static void hist_browser__refresh_dimensions(struct hist_browser *browser) static void hist_browser__reset(struct hist_browser *browser) { - browser->b.nr_entries = browser->hists->nr_entries; + /* + * The hists__remove_entry_filter() already folds non-filtered + * entries so we can assume it has 0 callchain rows. + */ + browser->nr_callchain_rows = 0; + + hist_browser__update_nr_entries(browser); + browser->b.nr_entries = hist_browser__nr_entries(browser); hist_browser__refresh_dimensions(browser); ui_browser__reset_index(&browser->b); } @@ -198,14 +228,16 @@ static bool hist_browser__toggle_fold(struct hist_browser *browser) struct hist_entry *he = browser->he_selection; hist_entry__init_have_children(he); - browser->hists->nr_entries -= he->nr_rows; + browser->b.nr_entries -= he->nr_rows; + browser->nr_callchain_rows -= he->nr_rows; if (he->ms.unfolded) he->nr_rows = callchain__count_rows(&he->sorted_chain); else he->nr_rows = 0; - browser->hists->nr_entries += he->nr_rows; - browser->b.nr_entries = browser->hists->nr_entries; + + browser->b.nr_entries += he->nr_rows; + browser->nr_callchain_rows += he->nr_rows; return true; } @@ -280,23 +312,27 @@ static void hist_entry__set_folding(struct hist_entry *he, bool unfold) he->nr_rows = 0; } -static void hists__set_folding(struct hists *hists, bool unfold) +static void +__hist_browser__set_folding(struct hist_browser *browser, bool unfold) { struct rb_node *nd; + struct hists *hists = browser->hists; - hists->nr_entries = 0; - - for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { + for (nd = rb_first(&hists->entries); + (nd = hists__filter_entries(nd, browser->min_pcnt)) != NULL; + nd = rb_next(nd)) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); hist_entry__set_folding(he, unfold); - hists->nr_entries += 1 + he->nr_rows; + browser->nr_callchain_rows += he->nr_rows; } } static void hist_browser__set_folding(struct hist_browser *browser, bool unfold) { - hists__set_folding(browser->hists, unfold); - browser->b.nr_entries = browser->hists->nr_entries; + browser->nr_callchain_rows = 0; + __hist_browser__set_folding(browser, unfold); + + browser->b.nr_entries = hist_browser__nr_entries(browser); /* Go to the start, we may be way after valid entries after a collapse */ ui_browser__reset_index(&browser->b); } @@ -310,8 +346,6 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser) "Or reduce the sampling frequency."); } -static void hist_browser__update_pcnt_entries(struct hist_browser *hb); - static int hist_browser__run(struct hist_browser *browser, const char *ev_name, struct hist_browser_timer *hbt) { @@ -320,9 +354,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, int delay_secs = hbt ? hbt->refresh : 0; browser->b.entries = &browser->hists->entries; - browser->b.nr_entries = browser->hists->nr_entries; - if (browser->min_pcnt) - browser->b.nr_entries = browser->nr_pcnt_entries; + browser->b.nr_entries = hist_browser__nr_entries(browser); hist_browser__refresh_dimensions(browser); hists__browser_title(browser->hists, title, sizeof(title), ev_name); @@ -339,13 +371,10 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, u64 nr_entries; hbt->timer(hbt->arg); - if (browser->min_pcnt) { - hist_browser__update_pcnt_entries(browser); - nr_entries = browser->nr_pcnt_entries; - } else { - nr_entries = browser->hists->nr_entries; - } + if (hist_browser__has_filter(browser)) + hist_browser__update_nr_entries(browser); + nr_entries = hist_browser__nr_entries(browser); ui_browser__update_nr_entries(&browser->b, nr_entries); if (browser->hists->stats.nr_lost_warned != @@ -587,99 +616,27 @@ struct hpp_arg { bool current_entry; }; -static int __hpp__color_callchain(struct hpp_arg *arg) +static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) { - if (!symbol_conf.use_callchain) - return 0; - - slsmg_printf("%c ", arg->folded_sign); - return 2; -} - -static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he, - u64 (*get_field)(struct hist_entry *), - int (*callchain_cb)(struct hpp_arg *)) -{ - int ret = 0; - double percent = 0.0; - struct hists *hists = he->hists; struct hpp_arg *arg = hpp->ptr; + int ret; + va_list args; + double percent; - if (hists->stats.total_period) - percent = 100.0 * get_field(he) / hists->stats.total_period; + va_start(args, fmt); + percent = va_arg(args, double); + va_end(args); ui_browser__set_percent_color(arg->b, percent, arg->current_entry); - if (callchain_cb) - ret += callchain_cb(arg); - - ret += scnprintf(hpp->buf, hpp->size, "%6.2f%%", percent); + ret = scnprintf(hpp->buf, hpp->size, fmt, percent); slsmg_printf("%s", hpp->buf); - if (symbol_conf.event_group) { - int prev_idx, idx_delta; - struct perf_evsel *evsel = hists_to_evsel(hists); - struct hist_entry *pair; - int nr_members = evsel->nr_members; - - if (nr_members <= 1) - goto out; - - prev_idx = perf_evsel__group_idx(evsel); - - list_for_each_entry(pair, &he->pairs.head, pairs.node) { - u64 period = get_field(pair); - u64 total = pair->hists->stats.total_period; - - if (!total) - continue; - - evsel = hists_to_evsel(pair->hists); - idx_delta = perf_evsel__group_idx(evsel) - prev_idx - 1; - - while (idx_delta--) { - /* - * zero-fill group members in the middle which - * have no sample - */ - ui_browser__set_percent_color(arg->b, 0.0, - arg->current_entry); - ret += scnprintf(hpp->buf, hpp->size, - " %6.2f%%", 0.0); - slsmg_printf("%s", hpp->buf); - } - - percent = 100.0 * period / total; - ui_browser__set_percent_color(arg->b, percent, - arg->current_entry); - ret += scnprintf(hpp->buf, hpp->size, - " %6.2f%%", percent); - slsmg_printf("%s", hpp->buf); - - prev_idx = perf_evsel__group_idx(evsel); - } - - idx_delta = nr_members - prev_idx - 1; - - while (idx_delta--) { - /* - * zero-fill group members at last which have no sample - */ - ui_browser__set_percent_color(arg->b, 0.0, - arg->current_entry); - ret += scnprintf(hpp->buf, hpp->size, - " %6.2f%%", 0.0); - slsmg_printf("%s", hpp->buf); - } - } -out: - if (!arg->current_entry || !arg->b->navkeypressed) - ui_browser__set_color(arg->b, HE_COLORSET_NORMAL); - + advance_hpp(hpp, ret); return ret; } -#define __HPP_COLOR_PERCENT_FN(_type, _field, _cb) \ +#define __HPP_COLOR_PERCENT_FN(_type, _field) \ static u64 __hpp_get_##_field(struct hist_entry *he) \ { \ return he->stat._field; \ @@ -690,21 +647,43 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\ struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__color_fmt(hpp, he, __hpp_get_##_field, _cb); \ + return __hpp__fmt(hpp, he, __hpp_get_##_field, " %6.2f%%", \ + __hpp__slsmg_color_printf, true); \ +} + +#define __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ +static u64 __hpp_get_acc_##_field(struct hist_entry *he) \ +{ \ + return he->stat_acc->_field; \ +} \ + \ +static int \ +hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\ + struct perf_hpp *hpp, \ + struct hist_entry *he) \ +{ \ + if (!symbol_conf.cumulate_callchain) { \ + int ret = scnprintf(hpp->buf, hpp->size, "%8s", "N/A"); \ + slsmg_printf("%s", hpp->buf); \ + \ + return ret; \ + } \ + return __hpp__fmt(hpp, he, __hpp_get_acc_##_field, " %6.2f%%", \ + __hpp__slsmg_color_printf, true); \ } -__HPP_COLOR_PERCENT_FN(overhead, period, __hpp__color_callchain) -__HPP_COLOR_PERCENT_FN(overhead_sys, period_sys, NULL) -__HPP_COLOR_PERCENT_FN(overhead_us, period_us, NULL) -__HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys, NULL) -__HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us, NULL) +__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) #undef __HPP_COLOR_PERCENT_FN +#undef __HPP_COLOR_ACC_PERCENT_FN void hist_browser__init_hpp(void) { - perf_hpp__init(); - perf_hpp__format[PERF_HPP__OVERHEAD].color = hist_browser__hpp_color_overhead; perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color = @@ -715,6 +694,8 @@ void hist_browser__init_hpp(void) hist_browser__hpp_color_overhead_guest_sys; perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_US].color = hist_browser__hpp_color_overhead_guest_us; + perf_hpp__format[PERF_HPP__OVERHEAD_ACC].color = + hist_browser__hpp_color_overhead_acc; } static int hist_browser__show_entry(struct hist_browser *browser, @@ -742,7 +723,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, if (row_offset == 0) { struct hpp_arg arg = { - .b = &browser->b, + .b = &browser->b, .folded_sign = folded_sign, .current_entry = current_entry, }; @@ -755,11 +736,27 @@ static int hist_browser__show_entry(struct hist_browser *browser, ui_browser__gotorc(&browser->b, row, 0); perf_hpp__for_each_format(fmt) { - if (!first) { + if (perf_hpp__should_skip(fmt)) + continue; + + if (current_entry && browser->b.navkeypressed) { + ui_browser__set_color(&browser->b, + HE_COLORSET_SELECTED); + } else { + ui_browser__set_color(&browser->b, + HE_COLORSET_NORMAL); + } + + if (first) { + if (symbol_conf.use_callchain) { + slsmg_printf("%c ", folded_sign); + width -= 2; + } + first = false; + } else { slsmg_printf(" "); width -= 2; } - first = false; if (fmt->color) { width -= fmt->color(fmt, &hpp, entry); @@ -773,8 +770,8 @@ static int hist_browser__show_entry(struct hist_browser *browser, if (!browser->b.navkeypressed) width += 1; - hist_entry__sort_snprintf(entry, s, sizeof(s), browser->hists); - slsmg_write_nstring(s, width); + slsmg_write_nstring("", width); + ++row; ++printed; } else @@ -811,12 +808,12 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) for (nd = browser->top; nd; nd = rb_next(nd)) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - float percent = h->stat.period * 100.0 / - hb->hists->stats.total_period; + float percent; if (h->filtered) continue; + percent = hist_entry__get_percent_limit(h); if (percent < hb->min_pcnt) continue; @@ -829,18 +826,13 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) } static struct rb_node *hists__filter_entries(struct rb_node *nd, - struct hists *hists, float min_pcnt) { while (nd != NULL) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - float percent = h->stat.period * 100.0 / - hists->stats.total_period; - - if (percent < min_pcnt) - return NULL; + float percent = hist_entry__get_percent_limit(h); - if (!h->filtered) + if (!h->filtered && percent >= min_pcnt) return nd; nd = rb_next(nd); @@ -850,13 +842,11 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd, } static struct rb_node *hists__filter_prev_entries(struct rb_node *nd, - struct hists *hists, float min_pcnt) { while (nd != NULL) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - float percent = h->stat.period * 100.0 / - hists->stats.total_period; + float percent = hist_entry__get_percent_limit(h); if (!h->filtered && percent >= min_pcnt) return nd; @@ -885,14 +875,14 @@ static void ui_browser__hists_seek(struct ui_browser *browser, switch (whence) { case SEEK_SET: nd = hists__filter_entries(rb_first(browser->entries), - hb->hists, hb->min_pcnt); + hb->min_pcnt); break; case SEEK_CUR: nd = browser->top; goto do_offset; case SEEK_END: nd = hists__filter_prev_entries(rb_last(browser->entries), - hb->hists, hb->min_pcnt); + hb->min_pcnt); first = false; break; default: @@ -935,8 +925,7 @@ do_offset: break; } } - nd = hists__filter_entries(rb_next(nd), hb->hists, - hb->min_pcnt); + nd = hists__filter_entries(rb_next(nd), hb->min_pcnt); if (nd == NULL) break; --offset; @@ -969,7 +958,7 @@ do_offset: } } - nd = hists__filter_prev_entries(rb_prev(nd), hb->hists, + nd = hists__filter_prev_entries(rb_prev(nd), hb->min_pcnt); if (nd == NULL) break; @@ -1108,27 +1097,35 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, struct hist_entry *he, FILE *fp) { char s[8192]; - double percent; int printed = 0; char folded_sign = ' '; + struct perf_hpp hpp = { + .buf = s, + .size = sizeof(s), + }; + struct perf_hpp_fmt *fmt; + bool first = true; + int ret; if (symbol_conf.use_callchain) folded_sign = hist_entry__folded(he); - hist_entry__sort_snprintf(he, s, sizeof(s), browser->hists); - percent = (he->stat.period * 100.0) / browser->hists->stats.total_period; - if (symbol_conf.use_callchain) printed += fprintf(fp, "%c ", folded_sign); - printed += fprintf(fp, " %5.2f%%", percent); - - if (symbol_conf.show_nr_samples) - printed += fprintf(fp, " %11u", he->stat.nr_events); + perf_hpp__for_each_format(fmt) { + if (perf_hpp__should_skip(fmt)) + continue; - if (symbol_conf.show_total_period) - printed += fprintf(fp, " %12" PRIu64, he->stat.period); + if (!first) { + ret = scnprintf(hpp.buf, hpp.size, " "); + advance_hpp(&hpp, ret); + } else + first = false; + ret = fmt->entry(fmt, &hpp, he); + advance_hpp(&hpp, ret); + } printed += fprintf(fp, "%s\n", rtrim(s)); if (folded_sign == '-') @@ -1140,7 +1137,6 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) { struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries), - browser->hists, browser->min_pcnt); int printed = 0; @@ -1148,8 +1144,7 @@ static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); printed += hist_browser__fprintf_entry(browser, h, fp); - nd = hists__filter_entries(rb_next(nd), browser->hists, - browser->min_pcnt); + nd = hists__filter_entries(rb_next(nd), browser->min_pcnt); } return printed; @@ -1231,6 +1226,11 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size, char buf[512]; size_t buflen = sizeof(buf); + if (symbol_conf.filter_relative) { + nr_samples = hists->stats.nr_non_filtered_samples; + nr_events = hists->stats.total_non_filtered_period; + } + if (perf_evsel__is_group_event(evsel)) { struct perf_evsel *pos; @@ -1238,8 +1238,13 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size, ev_name = buf; for_each_group_member(pos, evsel) { - nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; - nr_events += pos->hists.stats.total_period; + if (symbol_conf.filter_relative) { + nr_samples += pos->hists.stats.nr_non_filtered_samples; + nr_events += pos->hists.stats.total_non_filtered_period; + } else { + nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; + nr_events += pos->hists.stats.total_period; + } } } @@ -1255,7 +1260,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size, if (thread) printed += scnprintf(bf + printed, size - printed, ", Thread: %s(%d)", - (thread->comm_set ? thread->comm : ""), + (thread->comm_set ? thread__comm_str(thread) : ""), thread->tid); if (dso) printed += scnprintf(bf + printed, size - printed, @@ -1267,10 +1272,8 @@ static inline void free_popup_options(char **options, int n) { int i; - for (i = 0; i < n; ++i) { - free(options[i]); - options[i] = NULL; - } + for (i = 0; i < n; ++i) + zfree(&options[i]); } /* Check whether the browser is for 'top' or 'report' */ @@ -1329,7 +1332,7 @@ static int switch_data_file(void) abs_path[nr_options] = strdup(path); if (!abs_path[nr_options]) { - free(options[nr_options]); + zfree(&options[nr_options]); ui__warning("Can't search all data files due to memory shortage.\n"); fclose(file); break; @@ -1368,18 +1371,22 @@ close_file_and_continue: return ret; } -static void hist_browser__update_pcnt_entries(struct hist_browser *hb) +static void hist_browser__update_nr_entries(struct hist_browser *hb) { u64 nr_entries = 0; struct rb_node *nd = rb_first(&hb->hists->entries); - while (nd) { + if (hb->min_pcnt == 0) { + hb->nr_non_filtered_entries = hb->hists->nr_non_filtered_entries; + return; + } + + while ((nd = hists__filter_entries(nd, hb->min_pcnt)) != NULL) { nr_entries++; - nd = hists__filter_entries(rb_next(nd), hb->hists, - hb->min_pcnt); + nd = rb_next(nd); } - hb->nr_pcnt_entries = nr_entries; + hb->nr_non_filtered_entries = nr_entries; } static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, @@ -1400,12 +1407,43 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, char script_opt[64]; int delay_secs = hbt ? hbt->refresh : 0; +#define HIST_BROWSER_HELP_COMMON \ + "h/?/F1 Show this window\n" \ + "UP/DOWN/PGUP\n" \ + "PGDN/SPACE Navigate\n" \ + "q/ESC/CTRL+C Exit browser\n\n" \ + "For multiple event sessions:\n\n" \ + "TAB/UNTAB Switch events\n\n" \ + "For symbolic views (--sort has sym):\n\n" \ + "-> Zoom into DSO/Threads & Annotate current symbol\n" \ + "<- Zoom out\n" \ + "a Annotate current symbol\n" \ + "C Collapse all callchains\n" \ + "d Zoom into current DSO\n" \ + "E Expand all callchains\n" \ + "F Toggle percentage of filtered entries\n" \ + + /* help messages are sorted by lexical order of the hotkey */ + const char report_help[] = HIST_BROWSER_HELP_COMMON + "i Show header information\n" + "P Print histograms to perf.hist.N\n" + "r Run available scripts\n" + "s Switch to another data file in PWD\n" + "t Zoom into current Thread\n" + "V Verbose (DSO names in callchains, etc)\n" + "/ Filter symbol by name"; + const char top_help[] = HIST_BROWSER_HELP_COMMON + "P Print histograms to perf.hist.N\n" + "t Zoom into current Thread\n" + "V Verbose (DSO names in callchains, etc)\n" + "/ Filter symbol by name"; + if (browser == NULL) return -1; if (min_pcnt) { browser->min_pcnt = min_pcnt; - hist_browser__update_pcnt_entries(browser); + hist_browser__update_nr_entries(browser); } fstack = pstack__new(2); @@ -1484,29 +1522,19 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, if (is_report_browser(hbt)) goto do_data_switch; continue; + case 'i': + /* env->arch is NULL for live-mode (i.e. perf top) */ + if (env->arch) + tui__header_window(env); + continue; + case 'F': + symbol_conf.filter_relative ^= 1; + continue; case K_F1: case 'h': case '?': ui_browser__help_window(&browser->b, - "h/?/F1 Show this window\n" - "UP/DOWN/PGUP\n" - "PGDN/SPACE Navigate\n" - "q/ESC/CTRL+C Exit browser\n\n" - "For multiple event sessions:\n\n" - "TAB/UNTAB Switch events\n\n" - "For symbolic views (--sort has sym):\n\n" - "-> Zoom into DSO/Threads & Annotate current symbol\n" - "<- Zoom out\n" - "a Annotate current symbol\n" - "C Collapse all callchains\n" - "E Expand all callchains\n" - "d Zoom into current DSO\n" - "t Zoom into current Thread\n" - "r Run available scripts('perf report' only)\n" - "s Switch to another data file in PWD ('perf report' only)\n" - "P Print histograms to perf.hist.N\n" - "V Verbose (DSO names in callchains, etc)\n" - "/ Filter symbol by name"); + is_report_browser(hbt) ? report_help : top_help); continue; case K_ENTER: case K_RIGHT: @@ -1566,19 +1594,24 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, bi->to.sym->name) > 0) annotate_t = nr_options++; } else { - if (browser->selection != NULL && browser->selection->sym != NULL && - !browser->selection->map->dso->annotate_warned && - asprintf(&options[nr_options], "Annotate %s", - browser->selection->sym->name) > 0) - annotate = nr_options++; + !browser->selection->map->dso->annotate_warned) { + struct annotation *notes; + + notes = symbol__annotation(browser->selection->sym); + + if (notes->src && + asprintf(&options[nr_options], "Annotate %s", + browser->selection->sym->name) > 0) + annotate = nr_options++; + } } if (thread != NULL && asprintf(&options[nr_options], "Zoom %s %s(%d) thread", (browser->hists->thread_filter ? "out of" : "into"), - (thread->comm_set ? thread->comm : ""), + (thread->comm_set ? thread__comm_str(thread) : ""), thread->tid) > 0) zoom_thread = nr_options++; @@ -1598,7 +1631,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, struct symbol *sym; if (asprintf(&options[nr_options], "Run scripts for samples of thread [%s]", - browser->he_selection->thread->comm) > 0) + thread__comm_str(browser->he_selection->thread)) > 0) scripts_comm = nr_options++; sym = browser->he_selection->ms.sym; @@ -1629,6 +1662,7 @@ retry_popup_menu: if (choice == annotate || choice == annotate_t || choice == annotate_f) { struct hist_entry *he; + struct annotation *notes; int err; do_annotate: if (!objdump_path && perf_session_env__lookup_objdump(env)) @@ -1652,6 +1686,10 @@ do_annotate: he->ms.map = he->branch_info->to.map; } + notes = symbol__annotation(he->ms.sym); + if (!notes->src) + continue; + /* * Don't let this be freed, say, by hists__decay_entry. */ @@ -1679,14 +1717,14 @@ zoom_dso: zoom_out_dso: ui_helpline__pop(); browser->hists->dso_filter = NULL; - sort_dso.elide = false; + perf_hpp__set_elide(HISTC_DSO, false); } else { if (dso == NULL) continue; ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"", dso->kernel ? "the Kernel" : dso->short_name); browser->hists->dso_filter = dso; - sort_dso.elide = true; + perf_hpp__set_elide(HISTC_DSO, true); pstack__push(fstack, &browser->hists->dso_filter); } hists__filter_by_dso(hists); @@ -1698,13 +1736,13 @@ zoom_thread: zoom_out_thread: ui_helpline__pop(); browser->hists->thread_filter = NULL; - sort_thread.elide = false; + perf_hpp__set_elide(HISTC_THREAD, false); } else { ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"", - thread->comm_set ? thread->comm : "", + thread->comm_set ? thread__comm_str(thread) : "", thread->tid); browser->hists->thread_filter = thread; - sort_thread.elide = true; + perf_hpp__set_elide(HISTC_THREAD, false); pstack__push(fstack, &browser->hists->thread_filter); } hists__filter_by_thread(hists); @@ -1717,7 +1755,7 @@ do_scripts: memset(script_opt, 0, 64); if (choice == scripts_comm) - sprintf(script_opt, " -c %s ", browser->he_selection->thread->comm); + sprintf(script_opt, " -c %s ", thread__comm_str(browser->he_selection->thread)); if (choice == scripts_symbol) sprintf(script_opt, " -S %s ", browser->he_selection->ms.sym->name); @@ -1847,15 +1885,15 @@ browse_hists: switch (key) { case K_TAB: if (pos->node.next == &evlist->entries) - pos = list_entry(evlist->entries.next, struct perf_evsel, node); + pos = perf_evlist__first(evlist); else - pos = list_entry(pos->node.next, struct perf_evsel, node); + pos = perf_evsel__next(pos); goto browse_hists; case K_UNTAB: if (pos->node.prev == &evlist->entries) - pos = list_entry(evlist->entries.prev, struct perf_evsel, node); + pos = perf_evlist__last(evlist); else - pos = list_entry(pos->node.prev, struct perf_evsel, node); + pos = perf_evsel__prev(pos); goto browse_hists; case K_ESC: if (!ui_browser__dialog_yesno(&menu->b, @@ -1889,7 +1927,7 @@ out: return key; } -static bool filter_group_entries(struct ui_browser *self __maybe_unused, +static bool filter_group_entries(struct ui_browser *browser __maybe_unused, void *entry) { struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); @@ -1923,7 +1961,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, ui_helpline__push("Press ESC to exit"); - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { const char *ev_name = perf_evsel__name(pos); size_t line_len = strlen(ev_name) + 7; @@ -1943,8 +1981,7 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, single_entry: if (nr_entries == 1) { - struct perf_evsel *first = list_entry(evlist->entries.next, - struct perf_evsel, node); + struct perf_evsel *first = perf_evlist__first(evlist); const char *ev_name = perf_evsel__name(first); return perf_evsel__hists_browse(first, nr_entries, help, @@ -1956,9 +1993,10 @@ single_entry: struct perf_evsel *pos; nr_entries = 0; - list_for_each_entry(pos, &evlist->entries, node) + evlist__for_each(evlist, pos) { if (perf_evsel__is_group_leader(pos)) nr_entries++; + } if (nr_entries == 1) goto single_entry; |
