diff options
| author | Ingo Molnar <mingo@elte.hu> | 2012-03-12 15:46:35 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2012-03-12 15:47:05 -0400 |
| commit | bea95c152dee1791dd02cbc708afbb115bb00f9a (patch) | |
| tree | af9994c42c5fdd81ba3dadd7b812e2fa85273353 /tools/perf/util/ui | |
| parent | f9b4eeb809c6d031cc9561cc34dd691701cb2c2a (diff) | |
| parent | 24bff2dc0f77b1f186b7bdf30060caf3df191a68 (diff) | |
Merge branch 'perf/hw-branch-sampling' into perf/core
Merge reason: The 'perf record -b' hardware branch sampling feature is ready for upstream.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/ui')
| -rw-r--r-- | tools/perf/util/ui/browsers/hists.c | 102 |
1 files changed, 83 insertions, 19 deletions
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index bfba0490c098..de8ece8bcce3 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c | |||
| @@ -805,8 +805,11 @@ static struct hist_browser *hist_browser__new(struct hists *hists) | |||
| 805 | self->hists = hists; | 805 | self->hists = hists; |
| 806 | self->b.refresh = hist_browser__refresh; | 806 | self->b.refresh = hist_browser__refresh; |
| 807 | self->b.seek = ui_browser__hists_seek; | 807 | self->b.seek = ui_browser__hists_seek; |
| 808 | self->b.use_navkeypressed = true, | 808 | self->b.use_navkeypressed = true; |
| 809 | self->has_symbols = sort_sym.list.next != NULL; | 809 | if (sort__branch_mode == 1) |
| 810 | self->has_symbols = sort_sym_from.list.next != NULL; | ||
| 811 | else | ||
| 812 | self->has_symbols = sort_sym.list.next != NULL; | ||
| 810 | } | 813 | } |
| 811 | 814 | ||
| 812 | return self; | 815 | return self; |
| @@ -853,6 +856,16 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size, | |||
| 853 | return printed; | 856 | return printed; |
| 854 | } | 857 | } |
| 855 | 858 | ||
| 859 | static inline void free_popup_options(char **options, int n) | ||
| 860 | { | ||
| 861 | int i; | ||
| 862 | |||
| 863 | for (i = 0; i < n; ++i) { | ||
| 864 | free(options[i]); | ||
| 865 | options[i] = NULL; | ||
| 866 | } | ||
| 867 | } | ||
| 868 | |||
| 856 | static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | 869 | static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, |
| 857 | const char *helpline, const char *ev_name, | 870 | const char *helpline, const char *ev_name, |
| 858 | bool left_exits, | 871 | bool left_exits, |
| @@ -861,7 +874,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 861 | { | 874 | { |
| 862 | struct hists *self = &evsel->hists; | 875 | struct hists *self = &evsel->hists; |
| 863 | struct hist_browser *browser = hist_browser__new(self); | 876 | struct hist_browser *browser = hist_browser__new(self); |
| 877 | struct branch_info *bi; | ||
| 864 | struct pstack *fstack; | 878 | struct pstack *fstack; |
| 879 | char *options[16]; | ||
| 880 | int nr_options = 0; | ||
| 865 | int key = -1; | 881 | int key = -1; |
| 866 | 882 | ||
| 867 | if (browser == NULL) | 883 | if (browser == NULL) |
| @@ -873,13 +889,16 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 873 | 889 | ||
| 874 | ui_helpline__push(helpline); | 890 | ui_helpline__push(helpline); |
| 875 | 891 | ||
| 892 | memset(options, 0, sizeof(options)); | ||
| 893 | |||
| 876 | while (1) { | 894 | while (1) { |
| 877 | const struct thread *thread = NULL; | 895 | const struct thread *thread = NULL; |
| 878 | const struct dso *dso = NULL; | 896 | const struct dso *dso = NULL; |
| 879 | char *options[16]; | 897 | int choice = 0, |
| 880 | int nr_options = 0, choice = 0, i, | ||
| 881 | annotate = -2, zoom_dso = -2, zoom_thread = -2, | 898 | annotate = -2, zoom_dso = -2, zoom_thread = -2, |
| 882 | browse_map = -2; | 899 | annotate_f = -2, annotate_t = -2, browse_map = -2; |
| 900 | |||
| 901 | nr_options = 0; | ||
| 883 | 902 | ||
| 884 | key = hist_browser__run(browser, ev_name, timer, arg, delay_secs); | 903 | key = hist_browser__run(browser, ev_name, timer, arg, delay_secs); |
| 885 | 904 | ||
| @@ -887,7 +906,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 887 | thread = hist_browser__selected_thread(browser); | 906 | thread = hist_browser__selected_thread(browser); |
| 888 | dso = browser->selection->map ? browser->selection->map->dso : NULL; | 907 | dso = browser->selection->map ? browser->selection->map->dso : NULL; |
| 889 | } | 908 | } |
| 890 | |||
| 891 | switch (key) { | 909 | switch (key) { |
| 892 | case K_TAB: | 910 | case K_TAB: |
| 893 | case K_UNTAB: | 911 | case K_UNTAB: |
| @@ -902,7 +920,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 902 | if (!browser->has_symbols) { | 920 | if (!browser->has_symbols) { |
| 903 | ui_browser__warning(&browser->b, delay_secs * 2, | 921 | ui_browser__warning(&browser->b, delay_secs * 2, |
| 904 | "Annotation is only available for symbolic views, " | 922 | "Annotation is only available for symbolic views, " |
| 905 | "include \"sym\" in --sort to use it."); | 923 | "include \"sym*\" in --sort to use it."); |
| 906 | continue; | 924 | continue; |
| 907 | } | 925 | } |
| 908 | 926 | ||
| @@ -972,12 +990,34 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 972 | if (!browser->has_symbols) | 990 | if (!browser->has_symbols) |
| 973 | goto add_exit_option; | 991 | goto add_exit_option; |
| 974 | 992 | ||
| 975 | if (browser->selection != NULL && | 993 | if (sort__branch_mode == 1) { |
| 976 | browser->selection->sym != NULL && | 994 | bi = browser->he_selection->branch_info; |
| 977 | !browser->selection->map->dso->annotate_warned && | 995 | if (browser->selection != NULL && |
| 978 | asprintf(&options[nr_options], "Annotate %s", | 996 | bi && |
| 979 | browser->selection->sym->name) > 0) | 997 | bi->from.sym != NULL && |
| 980 | annotate = nr_options++; | 998 | !bi->from.map->dso->annotate_warned && |
| 999 | asprintf(&options[nr_options], "Annotate %s", | ||
| 1000 | bi->from.sym->name) > 0) | ||
| 1001 | annotate_f = nr_options++; | ||
| 1002 | |||
| 1003 | if (browser->selection != NULL && | ||
| 1004 | bi && | ||
| 1005 | bi->to.sym != NULL && | ||
| 1006 | !bi->to.map->dso->annotate_warned && | ||
| 1007 | (bi->to.sym != bi->from.sym || | ||
| 1008 | bi->to.map->dso != bi->from.map->dso) && | ||
| 1009 | asprintf(&options[nr_options], "Annotate %s", | ||
| 1010 | bi->to.sym->name) > 0) | ||
| 1011 | annotate_t = nr_options++; | ||
| 1012 | } else { | ||
| 1013 | |||
| 1014 | if (browser->selection != NULL && | ||
| 1015 | browser->selection->sym != NULL && | ||
| 1016 | !browser->selection->map->dso->annotate_warned && | ||
| 1017 | asprintf(&options[nr_options], "Annotate %s", | ||
| 1018 | browser->selection->sym->name) > 0) | ||
| 1019 | annotate = nr_options++; | ||
| 1020 | } | ||
| 981 | 1021 | ||
| 982 | if (thread != NULL && | 1022 | if (thread != NULL && |
| 983 | asprintf(&options[nr_options], "Zoom %s %s(%d) thread", | 1023 | asprintf(&options[nr_options], "Zoom %s %s(%d) thread", |
| @@ -998,25 +1038,39 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 998 | browse_map = nr_options++; | 1038 | browse_map = nr_options++; |
| 999 | add_exit_option: | 1039 | add_exit_option: |
| 1000 | options[nr_options++] = (char *)"Exit"; | 1040 | options[nr_options++] = (char *)"Exit"; |
| 1001 | 1041 | retry_popup_menu: | |
| 1002 | choice = ui__popup_menu(nr_options, options); | 1042 | choice = ui__popup_menu(nr_options, options); |
| 1003 | 1043 | ||
| 1004 | for (i = 0; i < nr_options - 1; ++i) | ||
| 1005 | free(options[i]); | ||
| 1006 | |||
| 1007 | if (choice == nr_options - 1) | 1044 | if (choice == nr_options - 1) |
| 1008 | break; | 1045 | break; |
| 1009 | 1046 | ||
| 1010 | if (choice == -1) | 1047 | if (choice == -1) { |
| 1048 | free_popup_options(options, nr_options - 1); | ||
| 1011 | continue; | 1049 | continue; |
| 1050 | } | ||
| 1012 | 1051 | ||
| 1013 | if (choice == annotate) { | 1052 | if (choice == annotate || choice == annotate_t || choice == annotate_f) { |
| 1014 | struct hist_entry *he; | 1053 | struct hist_entry *he; |
| 1015 | int err; | 1054 | int err; |
| 1016 | do_annotate: | 1055 | do_annotate: |
| 1017 | he = hist_browser__selected_entry(browser); | 1056 | he = hist_browser__selected_entry(browser); |
| 1018 | if (he == NULL) | 1057 | if (he == NULL) |
| 1019 | continue; | 1058 | continue; |
| 1059 | |||
| 1060 | /* | ||
| 1061 | * we stash the branch_info symbol + map into the | ||
| 1062 | * the ms so we don't have to rewrite all the annotation | ||
| 1063 | * code to use branch_info. | ||
| 1064 | * in branch mode, the ms struct is not used | ||
| 1065 | */ | ||
| 1066 | if (choice == annotate_f) { | ||
| 1067 | he->ms.sym = he->branch_info->from.sym; | ||
| 1068 | he->ms.map = he->branch_info->from.map; | ||
| 1069 | } else if (choice == annotate_t) { | ||
| 1070 | he->ms.sym = he->branch_info->to.sym; | ||
| 1071 | he->ms.map = he->branch_info->to.map; | ||
| 1072 | } | ||
| 1073 | |||
| 1020 | /* | 1074 | /* |
| 1021 | * Don't let this be freed, say, by hists__decay_entry. | 1075 | * Don't let this be freed, say, by hists__decay_entry. |
| 1022 | */ | 1076 | */ |
| @@ -1024,9 +1078,18 @@ do_annotate: | |||
| 1024 | err = hist_entry__tui_annotate(he, evsel->idx, | 1078 | err = hist_entry__tui_annotate(he, evsel->idx, |
| 1025 | timer, arg, delay_secs); | 1079 | timer, arg, delay_secs); |
| 1026 | he->used = false; | 1080 | he->used = false; |
| 1081 | /* | ||
| 1082 | * offer option to annotate the other branch source or target | ||
| 1083 | * (if they exists) when returning from annotate | ||
| 1084 | */ | ||
| 1085 | if ((err == 'q' || err == CTRL('c')) | ||
| 1086 | && annotate_t != -2 && annotate_f != -2) | ||
| 1087 | goto retry_popup_menu; | ||
| 1088 | |||
| 1027 | ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); | 1089 | ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); |
| 1028 | if (err) | 1090 | if (err) |
| 1029 | ui_browser__handle_resize(&browser->b); | 1091 | ui_browser__handle_resize(&browser->b); |
| 1092 | |||
| 1030 | } else if (choice == browse_map) | 1093 | } else if (choice == browse_map) |
| 1031 | map__browse(browser->selection->map); | 1094 | map__browse(browser->selection->map); |
| 1032 | else if (choice == zoom_dso) { | 1095 | else if (choice == zoom_dso) { |
| @@ -1072,6 +1135,7 @@ out_free_stack: | |||
| 1072 | pstack__delete(fstack); | 1135 | pstack__delete(fstack); |
| 1073 | out: | 1136 | out: |
| 1074 | hist_browser__delete(browser); | 1137 | hist_browser__delete(browser); |
| 1138 | free_popup_options(options, nr_options - 1); | ||
| 1075 | return key; | 1139 | return key; |
| 1076 | } | 1140 | } |
| 1077 | 1141 | ||
