aboutsummaryrefslogtreecommitdiffstats
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 {
25 struct map_symbol *selection; 25 struct map_symbol *selection;
26 int print_seq; 26 int print_seq;
27 bool show_dso; 27 bool show_dso;
28 bool has_symbols; 28 float min_pcnt;
29 u64 nr_pcnt_entries;
29}; 30};
30 31
31extern void hist_browser__init_hpp(void); 32extern void hist_browser__init_hpp(void);
@@ -309,6 +310,8 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
309 "Or reduce the sampling frequency."); 310 "Or reduce the sampling frequency.");
310} 311}
311 312
313static void hist_browser__update_pcnt_entries(struct hist_browser *hb);
314
312static int hist_browser__run(struct hist_browser *browser, const char *ev_name, 315static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
313 struct hist_browser_timer *hbt) 316 struct hist_browser_timer *hbt)
314{ 317{
@@ -318,6 +321,8 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
318 321
319 browser->b.entries = &browser->hists->entries; 322 browser->b.entries = &browser->hists->entries;
320 browser->b.nr_entries = browser->hists->nr_entries; 323 browser->b.nr_entries = browser->hists->nr_entries;
324 if (browser->min_pcnt)
325 browser->b.nr_entries = browser->nr_pcnt_entries;
321 326
322 hist_browser__refresh_dimensions(browser); 327 hist_browser__refresh_dimensions(browser);
323 hists__browser_title(browser->hists, title, sizeof(title), ev_name); 328 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,
330 key = ui_browser__run(&browser->b, delay_secs); 335 key = ui_browser__run(&browser->b, delay_secs);
331 336
332 switch (key) { 337 switch (key) {
333 case K_TIMER: 338 case K_TIMER: {
339 u64 nr_entries;
334 hbt->timer(hbt->arg); 340 hbt->timer(hbt->arg);
335 ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); 341
342 if (browser->min_pcnt) {
343 hist_browser__update_pcnt_entries(browser);
344 nr_entries = browser->nr_pcnt_entries;
345 } else {
346 nr_entries = browser->hists->nr_entries;
347 }
348
349 ui_browser__update_nr_entries(&browser->b, nr_entries);
336 350
337 if (browser->hists->stats.nr_lost_warned != 351 if (browser->hists->stats.nr_lost_warned !=
338 browser->hists->stats.nr_events[PERF_RECORD_LOST]) { 352 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,
344 hists__browser_title(browser->hists, title, sizeof(title), ev_name); 358 hists__browser_title(browser->hists, title, sizeof(title), ev_name);
345 ui_browser__show_title(&browser->b, title); 359 ui_browser__show_title(&browser->b, title);
346 continue; 360 continue;
361 }
347 case 'D': { /* Debug */ 362 case 'D': { /* Debug */
348 static int seq; 363 static int seq;
349 struct hist_entry *h = rb_entry(browser->b.top, 364 struct hist_entry *h = rb_entry(browser->b.top,
@@ -796,10 +811,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
796 811
797 for (nd = browser->top; nd; nd = rb_next(nd)) { 812 for (nd = browser->top; nd; nd = rb_next(nd)) {
798 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 813 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
814 float percent = h->stat.period * 100.0 /
815 hb->hists->stats.total_period;
799 816
800 if (h->filtered) 817 if (h->filtered)
801 continue; 818 continue;
802 819
820 if (percent < hb->min_pcnt)
821 continue;
822
803 row += hist_browser__show_entry(hb, h, row); 823 row += hist_browser__show_entry(hb, h, row);
804 if (row == browser->height) 824 if (row == browser->height)
805 break; 825 break;
@@ -808,10 +828,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
808 return row; 828 return row;
809} 829}
810 830
811static struct rb_node *hists__filter_entries(struct rb_node *nd) 831static struct rb_node *hists__filter_entries(struct rb_node *nd,
832 struct hists *hists,
833 float min_pcnt)
812{ 834{
813 while (nd != NULL) { 835 while (nd != NULL) {
814 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 836 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
837 float percent = h->stat.period * 100.0 /
838 hists->stats.total_period;
839
840 if (percent < min_pcnt)
841 return NULL;
842
815 if (!h->filtered) 843 if (!h->filtered)
816 return nd; 844 return nd;
817 845
@@ -821,11 +849,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd)
821 return NULL; 849 return NULL;
822} 850}
823 851
824static struct rb_node *hists__filter_prev_entries(struct rb_node *nd) 852static struct rb_node *hists__filter_prev_entries(struct rb_node *nd,
853 struct hists *hists,
854 float min_pcnt)
825{ 855{
826 while (nd != NULL) { 856 while (nd != NULL) {
827 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 857 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
828 if (!h->filtered) 858 float percent = h->stat.period * 100.0 /
859 hists->stats.total_period;
860
861 if (!h->filtered && percent >= min_pcnt)
829 return nd; 862 return nd;
830 863
831 nd = rb_prev(nd); 864 nd = rb_prev(nd);
@@ -840,6 +873,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
840 struct hist_entry *h; 873 struct hist_entry *h;
841 struct rb_node *nd; 874 struct rb_node *nd;
842 bool first = true; 875 bool first = true;
876 struct hist_browser *hb;
877
878 hb = container_of(browser, struct hist_browser, b);
843 879
844 if (browser->nr_entries == 0) 880 if (browser->nr_entries == 0)
845 return; 881 return;
@@ -848,13 +884,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
848 884
849 switch (whence) { 885 switch (whence) {
850 case SEEK_SET: 886 case SEEK_SET:
851 nd = hists__filter_entries(rb_first(browser->entries)); 887 nd = hists__filter_entries(rb_first(browser->entries),
888 hb->hists, hb->min_pcnt);
852 break; 889 break;
853 case SEEK_CUR: 890 case SEEK_CUR:
854 nd = browser->top; 891 nd = browser->top;
855 goto do_offset; 892 goto do_offset;
856 case SEEK_END: 893 case SEEK_END:
857 nd = hists__filter_prev_entries(rb_last(browser->entries)); 894 nd = hists__filter_prev_entries(rb_last(browser->entries),
895 hb->hists, hb->min_pcnt);
858 first = false; 896 first = false;
859 break; 897 break;
860 default: 898 default:
@@ -897,7 +935,8 @@ do_offset:
897 break; 935 break;
898 } 936 }
899 } 937 }
900 nd = hists__filter_entries(rb_next(nd)); 938 nd = hists__filter_entries(rb_next(nd), hb->hists,
939 hb->min_pcnt);
901 if (nd == NULL) 940 if (nd == NULL)
902 break; 941 break;
903 --offset; 942 --offset;
@@ -930,7 +969,8 @@ do_offset:
930 } 969 }
931 } 970 }
932 971
933 nd = hists__filter_prev_entries(rb_prev(nd)); 972 nd = hists__filter_prev_entries(rb_prev(nd), hb->hists,
973 hb->min_pcnt);
934 if (nd == NULL) 974 if (nd == NULL)
935 break; 975 break;
936 ++offset; 976 ++offset;
@@ -1099,14 +1139,17 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
1099 1139
1100static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) 1140static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
1101{ 1141{
1102 struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries)); 1142 struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
1143 browser->hists,
1144 browser->min_pcnt);
1103 int printed = 0; 1145 int printed = 0;
1104 1146
1105 while (nd) { 1147 while (nd) {
1106 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 1148 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
1107 1149
1108 printed += hist_browser__fprintf_entry(browser, h, fp); 1150 printed += hist_browser__fprintf_entry(browser, h, fp);
1109 nd = hists__filter_entries(rb_next(nd)); 1151 nd = hists__filter_entries(rb_next(nd), browser->hists,
1152 browser->min_pcnt);
1110 } 1153 }
1111 1154
1112 return printed; 1155 return printed;
@@ -1155,10 +1198,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
1155 browser->b.refresh = hist_browser__refresh; 1198 browser->b.refresh = hist_browser__refresh;
1156 browser->b.seek = ui_browser__hists_seek; 1199 browser->b.seek = ui_browser__hists_seek;
1157 browser->b.use_navkeypressed = true; 1200 browser->b.use_navkeypressed = true;
1158 if (sort__branch_mode == 1)
1159 browser->has_symbols = sort_sym_from.list.next != NULL;
1160 else
1161 browser->has_symbols = sort_sym.list.next != NULL;
1162 } 1201 }
1163 1202
1164 return browser; 1203 return browser;
@@ -1329,11 +1368,25 @@ close_file_and_continue:
1329 return ret; 1368 return ret;
1330} 1369}
1331 1370
1371static void hist_browser__update_pcnt_entries(struct hist_browser *hb)
1372{
1373 u64 nr_entries = 0;
1374 struct rb_node *nd = rb_first(&hb->hists->entries);
1375
1376 while (nd) {
1377 nr_entries++;
1378 nd = hists__filter_entries(rb_next(nd), hb->hists,
1379 hb->min_pcnt);
1380 }
1381
1382 hb->nr_pcnt_entries = nr_entries;
1383}
1332 1384
1333static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, 1385static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1334 const char *helpline, const char *ev_name, 1386 const char *helpline, const char *ev_name,
1335 bool left_exits, 1387 bool left_exits,
1336 struct hist_browser_timer *hbt, 1388 struct hist_browser_timer *hbt,
1389 float min_pcnt,
1337 struct perf_session_env *env) 1390 struct perf_session_env *env)
1338{ 1391{
1339 struct hists *hists = &evsel->hists; 1392 struct hists *hists = &evsel->hists;
@@ -1350,6 +1403,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1350 if (browser == NULL) 1403 if (browser == NULL)
1351 return -1; 1404 return -1;
1352 1405
1406 if (min_pcnt) {
1407 browser->min_pcnt = min_pcnt;
1408 hist_browser__update_pcnt_entries(browser);
1409 }
1410
1353 fstack = pstack__new(2); 1411 fstack = pstack__new(2);
1354 if (fstack == NULL) 1412 if (fstack == NULL)
1355 goto out; 1413 goto out;
@@ -1386,7 +1444,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1386 */ 1444 */
1387 goto out_free_stack; 1445 goto out_free_stack;
1388 case 'a': 1446 case 'a':
1389 if (!browser->has_symbols) { 1447 if (!sort__has_sym) {
1390 ui_browser__warning(&browser->b, delay_secs * 2, 1448 ui_browser__warning(&browser->b, delay_secs * 2,
1391 "Annotation is only available for symbolic views, " 1449 "Annotation is only available for symbolic views, "
1392 "include \"sym*\" in --sort to use it."); 1450 "include \"sym*\" in --sort to use it.");
@@ -1485,10 +1543,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1485 continue; 1543 continue;
1486 } 1544 }
1487 1545
1488 if (!browser->has_symbols) 1546 if (!sort__has_sym)
1489 goto add_exit_option; 1547 goto add_exit_option;
1490 1548
1491 if (sort__branch_mode == 1) { 1549 if (sort__mode == SORT_MODE__BRANCH) {
1492 bi = browser->he_selection->branch_info; 1550 bi = browser->he_selection->branch_info;
1493 if (browser->selection != NULL && 1551 if (browser->selection != NULL &&
1494 bi && 1552 bi &&
@@ -1689,6 +1747,7 @@ struct perf_evsel_menu {
1689 struct ui_browser b; 1747 struct ui_browser b;
1690 struct perf_evsel *selection; 1748 struct perf_evsel *selection;
1691 bool lost_events, lost_events_warned; 1749 bool lost_events, lost_events_warned;
1750 float min_pcnt;
1692 struct perf_session_env *env; 1751 struct perf_session_env *env;
1693}; 1752};
1694 1753
@@ -1782,6 +1841,7 @@ browse_hists:
1782 ev_name = perf_evsel__name(pos); 1841 ev_name = perf_evsel__name(pos);
1783 key = perf_evsel__hists_browse(pos, nr_events, help, 1842 key = perf_evsel__hists_browse(pos, nr_events, help,
1784 ev_name, true, hbt, 1843 ev_name, true, hbt,
1844 menu->min_pcnt,
1785 menu->env); 1845 menu->env);
1786 ui_browser__show_title(&menu->b, title); 1846 ui_browser__show_title(&menu->b, title);
1787 switch (key) { 1847 switch (key) {
@@ -1843,6 +1903,7 @@ static bool filter_group_entries(struct ui_browser *self __maybe_unused,
1843static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, 1903static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1844 int nr_entries, const char *help, 1904 int nr_entries, const char *help,
1845 struct hist_browser_timer *hbt, 1905 struct hist_browser_timer *hbt,
1906 float min_pcnt,
1846 struct perf_session_env *env) 1907 struct perf_session_env *env)
1847{ 1908{
1848 struct perf_evsel *pos; 1909 struct perf_evsel *pos;
@@ -1856,6 +1917,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1856 .nr_entries = nr_entries, 1917 .nr_entries = nr_entries,
1857 .priv = evlist, 1918 .priv = evlist,
1858 }, 1919 },
1920 .min_pcnt = min_pcnt,
1859 .env = env, 1921 .env = env,
1860 }; 1922 };
1861 1923
@@ -1874,6 +1936,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1874 1936
1875int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, 1937int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
1876 struct hist_browser_timer *hbt, 1938 struct hist_browser_timer *hbt,
1939 float min_pcnt,
1877 struct perf_session_env *env) 1940 struct perf_session_env *env)
1878{ 1941{
1879 int nr_entries = evlist->nr_entries; 1942 int nr_entries = evlist->nr_entries;
@@ -1885,7 +1948,8 @@ single_entry:
1885 const char *ev_name = perf_evsel__name(first); 1948 const char *ev_name = perf_evsel__name(first);
1886 1949
1887 return perf_evsel__hists_browse(first, nr_entries, help, 1950 return perf_evsel__hists_browse(first, nr_entries, help,
1888 ev_name, false, hbt, env); 1951 ev_name, false, hbt, min_pcnt,
1952 env);
1889 } 1953 }
1890 1954
1891 if (symbol_conf.event_group) { 1955 if (symbol_conf.event_group) {
@@ -1901,5 +1965,5 @@ single_entry:
1901 } 1965 }
1902 1966
1903 return __perf_evlist__tui_browse_hists(evlist, nr_entries, help, 1967 return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
1904 hbt, env); 1968 hbt, min_pcnt, env);
1905} 1969}