diff options
Diffstat (limited to 'tools/perf/ui/browsers/hists.c')
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 106 |
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 | ||
31 | extern void hist_browser__init_hpp(void); | 32 | extern 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 | ||
313 | static void hist_browser__update_pcnt_entries(struct hist_browser *hb); | ||
314 | |||
312 | static int hist_browser__run(struct hist_browser *browser, const char *ev_name, | 315 | static 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 | ||
811 | static struct rb_node *hists__filter_entries(struct rb_node *nd) | 831 | static 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 | ||
824 | static struct rb_node *hists__filter_prev_entries(struct rb_node *nd) | 852 | static 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 | ||
1100 | static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) | 1140 | static 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 | ||
1371 | static 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 | ||
1333 | static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | 1385 | static 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, | |||
1843 | static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, | 1903 | static 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 | ||
1875 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, | 1937 | int 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 | } |