summaryrefslogtreecommitdiff
path: root/tools/perf/ui/browsers/hists.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/ui/browsers/hists.c')
-rw-r--r--tools/perf/ui/browsers/hists.c106
1 files changed, 85 insertions, 21 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d88a2d0acb6d..fc0bd3843d34 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -25,7 +25,8 @@ struct hist_browser {
struct map_symbol *selection;
int print_seq;
bool show_dso;
- bool has_symbols;
+ float min_pcnt;
+ u64 nr_pcnt_entries;
};
extern void hist_browser__init_hpp(void);
@@ -309,6 +310,8 @@ 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)
{
@@ -318,6 +321,8 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
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;
hist_browser__refresh_dimensions(browser);
hists__browser_title(browser->hists, title, sizeof(title), ev_name);
@@ -330,9 +335,18 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
key = ui_browser__run(&browser->b, delay_secs);
switch (key) {
- case K_TIMER:
+ case K_TIMER: {
+ u64 nr_entries;
hbt->timer(hbt->arg);
- ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
+
+ if (browser->min_pcnt) {
+ hist_browser__update_pcnt_entries(browser);
+ nr_entries = browser->nr_pcnt_entries;
+ } else {
+ nr_entries = browser->hists->nr_entries;
+ }
+
+ ui_browser__update_nr_entries(&browser->b, nr_entries);
if (browser->hists->stats.nr_lost_warned !=
browser->hists->stats.nr_events[PERF_RECORD_LOST]) {
@@ -344,6 +358,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
hists__browser_title(browser->hists, title, sizeof(title), ev_name);
ui_browser__show_title(&browser->b, title);
continue;
+ }
case 'D': { /* Debug */
static int seq;
struct hist_entry *h = rb_entry(browser->b.top,
@@ -796,10 +811,15 @@ 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;
if (h->filtered)
continue;
+ if (percent < hb->min_pcnt)
+ continue;
+
row += hist_browser__show_entry(hb, h, row);
if (row == browser->height)
break;
@@ -808,10 +828,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
return row;
}
-static struct rb_node *hists__filter_entries(struct rb_node *nd)
+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;
+
if (!h->filtered)
return nd;
@@ -821,11 +849,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd)
return NULL;
}
-static struct rb_node *hists__filter_prev_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);
- if (!h->filtered)
+ float percent = h->stat.period * 100.0 /
+ hists->stats.total_period;
+
+ if (!h->filtered && percent >= min_pcnt)
return nd;
nd = rb_prev(nd);
@@ -840,6 +873,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
struct hist_entry *h;
struct rb_node *nd;
bool first = true;
+ struct hist_browser *hb;
+
+ hb = container_of(browser, struct hist_browser, b);
if (browser->nr_entries == 0)
return;
@@ -848,13 +884,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
switch (whence) {
case SEEK_SET:
- nd = hists__filter_entries(rb_first(browser->entries));
+ nd = hists__filter_entries(rb_first(browser->entries),
+ hb->hists, 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));
+ nd = hists__filter_prev_entries(rb_last(browser->entries),
+ hb->hists, hb->min_pcnt);
first = false;
break;
default:
@@ -897,7 +935,8 @@ do_offset:
break;
}
}
- nd = hists__filter_entries(rb_next(nd));
+ nd = hists__filter_entries(rb_next(nd), hb->hists,
+ hb->min_pcnt);
if (nd == NULL)
break;
--offset;
@@ -930,7 +969,8 @@ do_offset:
}
}
- nd = hists__filter_prev_entries(rb_prev(nd));
+ nd = hists__filter_prev_entries(rb_prev(nd), hb->hists,
+ hb->min_pcnt);
if (nd == NULL)
break;
++offset;
@@ -1099,14 +1139,17 @@ 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));
+ struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
+ browser->hists,
+ browser->min_pcnt);
int printed = 0;
while (nd) {
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));
+ nd = hists__filter_entries(rb_next(nd), browser->hists,
+ browser->min_pcnt);
}
return printed;
@@ -1155,10 +1198,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
browser->b.refresh = hist_browser__refresh;
browser->b.seek = ui_browser__hists_seek;
browser->b.use_navkeypressed = true;
- if (sort__branch_mode == 1)
- browser->has_symbols = sort_sym_from.list.next != NULL;
- else
- browser->has_symbols = sort_sym.list.next != NULL;
}
return browser;
@@ -1329,11 +1368,25 @@ close_file_and_continue:
return ret;
}
+static void hist_browser__update_pcnt_entries(struct hist_browser *hb)
+{
+ u64 nr_entries = 0;
+ struct rb_node *nd = rb_first(&hb->hists->entries);
+
+ while (nd) {
+ nr_entries++;
+ nd = hists__filter_entries(rb_next(nd), hb->hists,
+ hb->min_pcnt);
+ }
+
+ hb->nr_pcnt_entries = nr_entries;
+}
static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
const char *helpline, const char *ev_name,
bool left_exits,
struct hist_browser_timer *hbt,
+ float min_pcnt,
struct perf_session_env *env)
{
struct hists *hists = &evsel->hists;
@@ -1350,6 +1403,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (browser == NULL)
return -1;
+ if (min_pcnt) {
+ browser->min_pcnt = min_pcnt;
+ hist_browser__update_pcnt_entries(browser);
+ }
+
fstack = pstack__new(2);
if (fstack == NULL)
goto out;
@@ -1386,7 +1444,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
*/
goto out_free_stack;
case 'a':
- if (!browser->has_symbols) {
+ if (!sort__has_sym) {
ui_browser__warning(&browser->b, delay_secs * 2,
"Annotation is only available for symbolic views, "
"include \"sym*\" in --sort to use it.");
@@ -1485,10 +1543,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
continue;
}
- if (!browser->has_symbols)
+ if (!sort__has_sym)
goto add_exit_option;
- if (sort__branch_mode == 1) {
+ if (sort__mode == SORT_MODE__BRANCH) {
bi = browser->he_selection->branch_info;
if (browser->selection != NULL &&
bi &&
@@ -1689,6 +1747,7 @@ struct perf_evsel_menu {
struct ui_browser b;
struct perf_evsel *selection;
bool lost_events, lost_events_warned;
+ float min_pcnt;
struct perf_session_env *env;
};
@@ -1782,6 +1841,7 @@ browse_hists:
ev_name = perf_evsel__name(pos);
key = perf_evsel__hists_browse(pos, nr_events, help,
ev_name, true, hbt,
+ menu->min_pcnt,
menu->env);
ui_browser__show_title(&menu->b, title);
switch (key) {
@@ -1843,6 +1903,7 @@ static bool filter_group_entries(struct ui_browser *self __maybe_unused,
static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
int nr_entries, const char *help,
struct hist_browser_timer *hbt,
+ float min_pcnt,
struct perf_session_env *env)
{
struct perf_evsel *pos;
@@ -1856,6 +1917,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
.nr_entries = nr_entries,
.priv = evlist,
},
+ .min_pcnt = min_pcnt,
.env = env,
};
@@ -1874,6 +1936,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
struct hist_browser_timer *hbt,
+ float min_pcnt,
struct perf_session_env *env)
{
int nr_entries = evlist->nr_entries;
@@ -1885,7 +1948,8 @@ single_entry:
const char *ev_name = perf_evsel__name(first);
return perf_evsel__hists_browse(first, nr_entries, help,
- ev_name, false, hbt, env);
+ ev_name, false, hbt, min_pcnt,
+ env);
}
if (symbol_conf.event_group) {
@@ -1901,5 +1965,5 @@ single_entry:
}
return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
- hbt, env);
+ hbt, min_pcnt, env);
}