aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2013-02-07 04:02:08 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-02-14 12:59:27 -0500
commit2b676bf068916046151277f27113f80828e33001 (patch)
tree2f508debbd3bc103ed64887914d8f65f590950b6 /tools/perf
parente3a34029c635b7dee06e51d99441578b96c7d463 (diff)
perf ui/gtk: Implement basic GTK2 annotation browser
Basic implementation of perf annotate on GTK2. Currently only shows first symbol. Add a new --gtk option to use it. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Pekka Enberg <penberg@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1360227734-375-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-annotate.txt4
-rw-r--r--tools/perf/Makefile1
-rw-r--r--tools/perf/builtin-annotate.c10
-rw-r--r--tools/perf/ui/gtk/annotate.c185
-rw-r--r--tools/perf/ui/setup.c2
-rw-r--r--tools/perf/util/annotate.h20
6 files changed, 218 insertions, 4 deletions
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index c8ffd9fd5c6a..e5e1d06efc37 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -61,11 +61,13 @@ OPTIONS
61 61
62--stdio:: Use the stdio interface. 62--stdio:: Use the stdio interface.
63 63
64--tui:: Use the TUI interface Use of --tui requires a tty, if one is not 64--tui:: Use the TUI interface. Use of --tui requires a tty, if one is not
65 present, as when piping to other commands, the stdio interface is 65 present, as when piping to other commands, the stdio interface is
66 used. This interfaces starts by centering on the line with more 66 used. This interfaces starts by centering on the line with more
67 samples, TAB/UNTAB cycles through the lines with more samples. 67 samples, TAB/UNTAB cycles through the lines with more samples.
68 68
69--gtk:: Use the GTK interface.
70
69-C:: 71-C::
70--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can 72--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can
71 be provided as a comma-separated list with no space: 0,1. Ranges of 73 be provided as a comma-separated list with no space: 0,1. Ranges of
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index a158309a65ef..1c8df6f9c4d9 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -698,6 +698,7 @@ ifndef NO_GTK2
698 LIB_OBJS += $(OUTPUT)ui/gtk/util.o 698 LIB_OBJS += $(OUTPUT)ui/gtk/util.o
699 LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o 699 LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
700 LIB_OBJS += $(OUTPUT)ui/gtk/progress.o 700 LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
701 LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
701 endif 702 endif
702endif 703endif
703 704
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 95a2ad3f043e..9d758c9611a5 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -34,7 +34,7 @@
34 34
35struct perf_annotate { 35struct perf_annotate {
36 struct perf_tool tool; 36 struct perf_tool tool;
37 bool force, use_tui, use_stdio; 37 bool force, use_tui, use_stdio, use_gtk;
38 bool full_paths; 38 bool full_paths;
39 bool print_line; 39 bool print_line;
40 const char *sym_hist_filter; 40 const char *sym_hist_filter;
@@ -138,7 +138,10 @@ find_next:
138 continue; 138 continue;
139 } 139 }
140 140
141 if (use_browser > 0) { 141 if (use_browser == 2) {
142 hist_entry__gtk_annotate(he, evidx, NULL);
143 return;
144 } else if (use_browser == 1) {
142 key = hist_entry__tui_annotate(he, evidx, NULL); 145 key = hist_entry__tui_annotate(he, evidx, NULL);
143 switch (key) { 146 switch (key) {
144 case K_RIGHT: 147 case K_RIGHT:
@@ -270,6 +273,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
270 "be more verbose (show symbol address, etc)"), 273 "be more verbose (show symbol address, etc)"),
271 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 274 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
272 "dump raw trace in ASCII"), 275 "dump raw trace in ASCII"),
276 OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
273 OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"), 277 OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"),
274 OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"), 278 OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"),
275 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 279 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
@@ -300,6 +304,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
300 use_browser = 0; 304 use_browser = 0;
301 else if (annotate.use_tui) 305 else if (annotate.use_tui)
302 use_browser = 1; 306 use_browser = 1;
307 else if (annotate.use_gtk)
308 use_browser = 2;
303 309
304 setup_browser(true); 310 setup_browser(true);
305 311
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
new file mode 100644
index 000000000000..19d84fa327af
--- /dev/null
+++ b/tools/perf/ui/gtk/annotate.c
@@ -0,0 +1,185 @@
1#include "gtk.h"
2#include "util/debug.h"
3#include "util/annotate.h"
4#include "ui/helpline.h"
5
6
7enum {
8 ANN_COL__PERCENT,
9 ANN_COL__OFFSET,
10 ANN_COL__LINE,
11
12 MAX_ANN_COLS
13};
14
15static const char *const col_names[] = {
16 "Overhead",
17 "Offset",
18 "Line"
19};
20
21static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym,
22 struct disasm_line *dl, int evidx)
23{
24 struct sym_hist *symhist;
25 double percent = 0.0;
26 const char *markup;
27 int ret = 0;
28
29 strcpy(buf, "");
30
31 if (dl->offset == (s64) -1)
32 return 0;
33
34 symhist = annotation__histogram(symbol__annotation(sym), evidx);
35 if (!symhist->addr[dl->offset])
36 return 0;
37
38 percent = 100.0 * symhist->addr[dl->offset] / symhist->sum;
39
40 markup = perf_gtk__get_percent_color(percent);
41 if (markup)
42 ret += scnprintf(buf, size, "%s", markup);
43 ret += scnprintf(buf + ret, size - ret, "%6.2f%%", percent);
44 if (markup)
45 ret += scnprintf(buf + ret, size - ret, "</span>");
46
47 return ret;
48}
49
50static int perf_gtk__get_offset(char *buf, size_t size, struct symbol *sym,
51 struct map *map, struct disasm_line *dl)
52{
53 u64 start = map__rip_2objdump(map, sym->start);
54
55 strcpy(buf, "");
56
57 if (dl->offset == (s64) -1)
58 return 0;
59
60 return scnprintf(buf, size, "%"PRIx64, start + dl->offset);
61}
62
63static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
64 struct map *map, int evidx,
65 struct hist_browser_timer *hbt __maybe_unused)
66{
67 struct disasm_line *pos, *n;
68 struct annotation *notes;
69 GType col_types[MAX_ANN_COLS];
70 GtkCellRenderer *renderer;
71 GtkListStore *store;
72 GtkWidget *view;
73 int i;
74 char s[512];
75
76 if (map->dso->annotate_warned)
77 return -1;
78
79 if (symbol__annotate(sym, map, 0) < 0) {
80 ui__error("%s", ui_helpline__current);
81 return -1;
82 }
83
84 notes = symbol__annotation(sym);
85
86 for (i = 0; i < MAX_ANN_COLS; i++) {
87 col_types[i] = G_TYPE_STRING;
88 }
89 store = gtk_list_store_newv(MAX_ANN_COLS, col_types);
90
91 view = gtk_tree_view_new();
92 renderer = gtk_cell_renderer_text_new();
93
94 for (i = 0; i < MAX_ANN_COLS; i++) {
95 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
96 -1, col_names[i], renderer,
97 i == ANN_COL__PERCENT ? "markup" : "text",
98 i, NULL);
99 }
100
101 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
102 g_object_unref(GTK_TREE_MODEL(store));
103
104 list_for_each_entry(pos, &notes->src->source, node) {
105 GtkTreeIter iter;
106
107 gtk_list_store_append(store, &iter);
108
109 if (perf_gtk__get_percent(s, sizeof(s), sym, pos, evidx))
110 gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1);
111 if (perf_gtk__get_offset(s, sizeof(s), sym, map, pos))
112 gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1);
113 gtk_list_store_set(store, &iter, ANN_COL__LINE, pos->line, -1);
114 }
115
116 gtk_container_add(GTK_CONTAINER(window), view);
117
118 list_for_each_entry_safe(pos, n, &notes->src->source, node) {
119 list_del(&pos->node);
120 disasm_line__free(pos);
121 }
122
123 return 0;
124}
125
126int symbol__gtk_annotate(struct symbol *sym, struct map *map, int evidx,
127 struct hist_browser_timer *hbt)
128{
129 GtkWidget *vbox;
130 GtkWidget *notebook;
131 GtkWidget *infobar;
132 GtkWidget *statbar;
133 GtkWidget *window;
134 GtkWidget *scrolled_window;
135 GtkWidget *tab_label;
136
137 signal(SIGSEGV, perf_gtk__signal);
138 signal(SIGFPE, perf_gtk__signal);
139 signal(SIGINT, perf_gtk__signal);
140 signal(SIGQUIT, perf_gtk__signal);
141 signal(SIGTERM, perf_gtk__signal);
142
143 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
144 gtk_window_set_title(GTK_WINDOW(window), "perf annotate");
145
146 g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
147
148 pgctx = perf_gtk__activate_context(window);
149 if (!pgctx)
150 return -1;
151
152 vbox = gtk_vbox_new(FALSE, 0);
153 notebook = gtk_notebook_new();
154 scrolled_window = gtk_scrolled_window_new(NULL, NULL);
155 tab_label = gtk_label_new(sym->name);
156
157 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
158 GTK_POLICY_AUTOMATIC,
159 GTK_POLICY_AUTOMATIC);
160
161 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window,
162 tab_label);
163 gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
164
165 infobar = perf_gtk__setup_info_bar();
166 if (infobar)
167 gtk_box_pack_start(GTK_BOX(vbox), infobar, FALSE, FALSE, 0);
168
169 statbar = perf_gtk__setup_statusbar();
170 gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0);
171
172 gtk_container_add(GTK_CONTAINER(window), vbox);
173
174 perf_gtk__annotate_symbol(scrolled_window, sym, map, evidx, hbt);
175
176 gtk_widget_show_all(window);
177
178 perf_gtk__resize_window(window);
179 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
180
181 gtk_main();
182
183 perf_gtk__deactivate_context(&pgctx);
184 return 0;
185}
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index 166f13df3134..ae6a789cb0f6 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -8,7 +8,7 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
8 8
9void setup_browser(bool fallback_to_pager) 9void setup_browser(bool fallback_to_pager)
10{ 10{
11 if (!isatty(1) || dump_trace) 11 if (use_browser < 2 && (!isatty(1) || dump_trace))
12 use_browser = 0; 12 use_browser = 0;
13 13
14 /* default to TUI */ 14 /* default to TUI */
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 8eec94358a4a..a8ccbda4aeb7 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -6,6 +6,7 @@
6#include "types.h" 6#include "types.h"
7#include "symbol.h" 7#include "symbol.h"
8#include "hist.h" 8#include "hist.h"
9#include "sort.h"
9#include <linux/list.h> 10#include <linux/list.h>
10#include <linux/rbtree.h> 11#include <linux/rbtree.h>
11#include <pthread.h> 12#include <pthread.h>
@@ -154,6 +155,25 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
154} 155}
155#endif 156#endif
156 157
158#ifdef GTK2_SUPPORT
159int symbol__gtk_annotate(struct symbol *sym, struct map *map, int evidx,
160 struct hist_browser_timer *hbt);
161
162static inline int hist_entry__gtk_annotate(struct hist_entry *he, int evidx,
163 struct hist_browser_timer *hbt)
164{
165 return symbol__gtk_annotate(he->ms.sym, he->ms.map, evidx, hbt);
166}
167#else
168static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
169 int evidx __maybe_unused,
170 struct hist_browser_timer *hbt
171 __maybe_unused)
172{
173 return 0;
174}
175#endif
176
157extern const char *disassembler_style; 177extern const char *disassembler_style;
158 178
159#endif /* __PERF_ANNOTATE_H */ 179#endif /* __PERF_ANNOTATE_H */