diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-23 21:36:51 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-23 21:36:51 -0400 |
commit | d67f088e084755bdceb4f15bc6e05e309db1eea7 (patch) | |
tree | 6eaae7aed4f990233e73851053f2a36b32ce55b2 /tools/perf/util/newt.c | |
parent | 44bf460649a9b91f291176097e9d7e846e8c001e (diff) |
perf report: Support multiple events on the TUI
The hists__tty_browse_tree function was created with the loop to print
all events, and its equivalent, hists__tui_browse_tree, was created in a
similar fashion, where it is possible to switch among the multiple
events, if present, using TAB to go the next event, and shift+TAB
(UNTAB) to go to the previous.
The report TUI now shows as the window title the name of the event and a
leak was fixed wrt pstacks.
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/newt.c')
-rw-r--r-- | tools/perf/util/newt.c | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index ffd04720b754..d54c540f49db 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
@@ -842,6 +842,8 @@ static int hist_browser__populate(struct hist_browser *self, struct hists *hists | |||
842 | newtFormAddHotKey(self->form, 'h'); | 842 | newtFormAddHotKey(self->form, 'h'); |
843 | newtFormAddHotKey(self->form, NEWT_KEY_F1); | 843 | newtFormAddHotKey(self->form, NEWT_KEY_F1); |
844 | newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); | 844 | newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); |
845 | newtFormAddHotKey(self->form, NEWT_KEY_TAB); | ||
846 | newtFormAddHotKey(self->form, NEWT_KEY_UNTAB); | ||
845 | newtFormAddComponents(self->form, self->tree, NULL); | 847 | newtFormAddComponents(self->form, self->tree, NULL); |
846 | self->selection = newt__symbol_tree_get_current(self->tree); | 848 | self->selection = newt__symbol_tree_get_current(self->tree); |
847 | 849 | ||
@@ -873,7 +875,7 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *self) | |||
873 | return he ? he->thread : NULL; | 875 | return he ? he->thread : NULL; |
874 | } | 876 | } |
875 | 877 | ||
876 | static int hist_browser__title(char *bf, size_t size, const char *input_name, | 878 | static int hist_browser__title(char *bf, size_t size, const char *ev_name, |
877 | const struct dso *dso, const struct thread *thread) | 879 | const struct dso *dso, const struct thread *thread) |
878 | { | 880 | { |
879 | int printed = 0; | 881 | int printed = 0; |
@@ -887,18 +889,18 @@ static int hist_browser__title(char *bf, size_t size, const char *input_name, | |||
887 | printed += snprintf(bf + printed, size - printed, | 889 | printed += snprintf(bf + printed, size - printed, |
888 | "%sDSO: %s", thread ? " " : "", | 890 | "%sDSO: %s", thread ? " " : "", |
889 | dso->short_name); | 891 | dso->short_name); |
890 | return printed ?: snprintf(bf, size, "Report: %s", input_name); | 892 | return printed ?: snprintf(bf, size, "Event: %s", ev_name); |
891 | } | 893 | } |
892 | 894 | ||
893 | int hists__browse(struct hists *self, const char *helpline, const char *input_name) | 895 | int hists__browse(struct hists *self, const char *helpline, const char *ev_name) |
894 | { | 896 | { |
895 | struct hist_browser *browser = hist_browser__new(); | 897 | struct hist_browser *browser = hist_browser__new(); |
896 | struct pstack *fstack = pstack__new(2); | 898 | struct pstack *fstack; |
897 | const struct thread *thread_filter = NULL; | 899 | const struct thread *thread_filter = NULL; |
898 | const struct dso *dso_filter = NULL; | 900 | const struct dso *dso_filter = NULL; |
899 | struct newtExitStruct es; | 901 | struct newtExitStruct es; |
900 | char msg[160]; | 902 | char msg[160]; |
901 | int err = -1; | 903 | int key = -1; |
902 | 904 | ||
903 | if (browser == NULL) | 905 | if (browser == NULL) |
904 | return -1; | 906 | return -1; |
@@ -909,7 +911,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na | |||
909 | 911 | ||
910 | ui_helpline__push(helpline); | 912 | ui_helpline__push(helpline); |
911 | 913 | ||
912 | hist_browser__title(msg, sizeof(msg), input_name, | 914 | hist_browser__title(msg, sizeof(msg), ev_name, |
913 | dso_filter, thread_filter); | 915 | dso_filter, thread_filter); |
914 | if (hist_browser__populate(browser, self, msg) < 0) | 916 | if (hist_browser__populate(browser, self, msg) < 0) |
915 | goto out_free_stack; | 917 | goto out_free_stack; |
@@ -927,10 +929,23 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na | |||
927 | dso = browser->selection->map ? browser->selection->map->dso : NULL; | 929 | dso = browser->selection->map ? browser->selection->map->dso : NULL; |
928 | 930 | ||
929 | if (es.reason == NEWT_EXIT_HOTKEY) { | 931 | if (es.reason == NEWT_EXIT_HOTKEY) { |
930 | if (es.u.key == NEWT_KEY_F1) | 932 | key = es.u.key; |
933 | |||
934 | switch (key) { | ||
935 | case NEWT_KEY_F1: | ||
931 | goto do_help; | 936 | goto do_help; |
937 | case NEWT_KEY_TAB: | ||
938 | case NEWT_KEY_UNTAB: | ||
939 | /* | ||
940 | * Exit the browser, let hists__browser_tree | ||
941 | * go to the next or previous | ||
942 | */ | ||
943 | goto out_free_stack; | ||
944 | default:; | ||
945 | } | ||
932 | 946 | ||
933 | switch (toupper(es.u.key)) { | 947 | key = toupper(key); |
948 | switch (key) { | ||
934 | case 'A': | 949 | case 'A': |
935 | if (browser->selection->map == NULL && | 950 | if (browser->selection->map == NULL && |
936 | browser->selection->map->dso->annotate_warned) | 951 | browser->selection->map->dso->annotate_warned) |
@@ -953,8 +968,8 @@ do_help: | |||
953 | continue; | 968 | continue; |
954 | default:; | 969 | default:; |
955 | } | 970 | } |
956 | if (is_exit_key(es.u.key)) { | 971 | if (is_exit_key(key)) { |
957 | if (es.u.key == NEWT_KEY_ESCAPE) { | 972 | if (key == NEWT_KEY_ESCAPE) { |
958 | if (dialog_yesno("Do you really want to exit?")) | 973 | if (dialog_yesno("Do you really want to exit?")) |
959 | break; | 974 | break; |
960 | else | 975 | else |
@@ -1041,7 +1056,7 @@ zoom_out_dso: | |||
1041 | pstack__push(fstack, &dso_filter); | 1056 | pstack__push(fstack, &dso_filter); |
1042 | } | 1057 | } |
1043 | hists__filter_by_dso(self, dso_filter); | 1058 | hists__filter_by_dso(self, dso_filter); |
1044 | hist_browser__title(msg, sizeof(msg), input_name, | 1059 | hist_browser__title(msg, sizeof(msg), ev_name, |
1045 | dso_filter, thread_filter); | 1060 | dso_filter, thread_filter); |
1046 | if (hist_browser__populate(browser, self, msg) < 0) | 1061 | if (hist_browser__populate(browser, self, msg) < 0) |
1047 | goto out; | 1062 | goto out; |
@@ -1060,18 +1075,49 @@ zoom_out_thread: | |||
1060 | pstack__push(fstack, &thread_filter); | 1075 | pstack__push(fstack, &thread_filter); |
1061 | } | 1076 | } |
1062 | hists__filter_by_thread(self, thread_filter); | 1077 | hists__filter_by_thread(self, thread_filter); |
1063 | hist_browser__title(msg, sizeof(msg), input_name, | 1078 | hist_browser__title(msg, sizeof(msg), ev_name, |
1064 | dso_filter, thread_filter); | 1079 | dso_filter, thread_filter); |
1065 | if (hist_browser__populate(browser, self, msg) < 0) | 1080 | if (hist_browser__populate(browser, self, msg) < 0) |
1066 | goto out; | 1081 | goto out; |
1067 | } | 1082 | } |
1068 | } | 1083 | } |
1069 | err = 0; | ||
1070 | out_free_stack: | 1084 | out_free_stack: |
1071 | pstack__delete(fstack); | 1085 | pstack__delete(fstack); |
1072 | out: | 1086 | out: |
1073 | hist_browser__delete(browser); | 1087 | hist_browser__delete(browser); |
1074 | return err; | 1088 | return key; |
1089 | } | ||
1090 | |||
1091 | int hists__tui_browse_tree(struct rb_root *self, const char *help) | ||
1092 | { | ||
1093 | struct rb_node *first = rb_first(self), *nd = first, *next; | ||
1094 | int key = 0; | ||
1095 | |||
1096 | while (nd) { | ||
1097 | struct hists *hists = rb_entry(nd, struct hists, rb_node); | ||
1098 | const char *ev_name = __event_name(hists->type, hists->config); | ||
1099 | |||
1100 | key = hists__browse(hists, help, ev_name); | ||
1101 | |||
1102 | if (is_exit_key(key)) | ||
1103 | break; | ||
1104 | |||
1105 | switch (key) { | ||
1106 | case NEWT_KEY_TAB: | ||
1107 | next = rb_next(nd); | ||
1108 | if (next) | ||
1109 | nd = next; | ||
1110 | break; | ||
1111 | case NEWT_KEY_UNTAB: | ||
1112 | if (nd == first) | ||
1113 | continue; | ||
1114 | nd = rb_prev(nd); | ||
1115 | default: | ||
1116 | break; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | return key; | ||
1075 | } | 1121 | } |
1076 | 1122 | ||
1077 | static struct newtPercentTreeColors { | 1123 | static struct newtPercentTreeColors { |