diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Makefile | 7 | ||||
-rw-r--r-- | tools/perf/util/debug.h | 1 | ||||
-rw-r--r-- | tools/perf/util/newt.c | 132 | ||||
-rw-r--r-- | tools/perf/util/ui/browser.h | 1 | ||||
-rw-r--r-- | tools/perf/util/ui/browsers/annotate.c | 114 | ||||
-rw-r--r-- | tools/perf/util/ui/libslang.h | 27 |
6 files changed, 151 insertions, 131 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 528c91469c0d..ae443b68e519 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -158,7 +158,7 @@ all:: | |||
158 | # Define NO_DWARF if you do not want debug-info analysis feature at all. | 158 | # Define NO_DWARF if you do not want debug-info analysis feature at all. |
159 | 159 | ||
160 | $(shell sh -c 'mkdir -p $(OUTPUT)scripts/{perl,python}/Perf-Trace-Util/' 2> /dev/null) | 160 | $(shell sh -c 'mkdir -p $(OUTPUT)scripts/{perl,python}/Perf-Trace-Util/' 2> /dev/null) |
161 | $(shell sh -c 'mkdir -p $(OUTPUT)util/{ui,scripting-engines}/' 2> /dev/null) | 161 | $(shell sh -c 'mkdir -p $(OUTPUT)util/{ui/browsers,scripting-engines}/' 2> /dev/null) |
162 | $(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null) | 162 | $(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null) |
163 | 163 | ||
164 | $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE | 164 | $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE |
@@ -569,10 +569,12 @@ else | |||
569 | EXTLIBS += -lnewt -lslang | 569 | EXTLIBS += -lnewt -lslang |
570 | LIB_OBJS += $(OUTPUT)util/newt.o | 570 | LIB_OBJS += $(OUTPUT)util/newt.o |
571 | LIB_OBJS += $(OUTPUT)util/ui/browser.o | 571 | LIB_OBJS += $(OUTPUT)util/ui/browser.o |
572 | LIB_OBJS += $(OUTPUT)util/ui/browsers/annotate.o | ||
572 | LIB_OBJS += $(OUTPUT)util/ui/helpline.o | 573 | LIB_OBJS += $(OUTPUT)util/ui/helpline.o |
573 | LIB_OBJS += $(OUTPUT)util/ui/progress.o | 574 | LIB_OBJS += $(OUTPUT)util/ui/progress.o |
574 | LIB_H += util/ui/browser.h | 575 | LIB_H += util/ui/browser.h |
575 | LIB_H += util/ui/helpline.h | 576 | LIB_H += util/ui/helpline.h |
577 | LIB_H += util/ui/libslang.h | ||
576 | LIB_H += util/ui/progress.h | 578 | LIB_H += util/ui/progress.h |
577 | endif | 579 | endif |
578 | endif | 580 | endif |
@@ -977,6 +979,9 @@ $(OUTPUT)util/newt.o: util/newt.c $(OUTPUT)PERF-CFLAGS | |||
977 | $(OUTPUT)util/ui/browser.o: util/ui/browser.c $(OUTPUT)PERF-CFLAGS | 979 | $(OUTPUT)util/ui/browser.o: util/ui/browser.c $(OUTPUT)PERF-CFLAGS |
978 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< | 980 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< |
979 | 981 | ||
982 | $(OUTPUT)util/ui/browsers/annotate.o: util/ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS | ||
983 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< | ||
984 | |||
980 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS | 985 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS |
981 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | 986 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< |
982 | 987 | ||
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index a929b06cfc0a..ba4892e49be2 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h | |||
@@ -30,6 +30,7 @@ static inline void ui_progress__update(struct ui_progress *self __used, | |||
30 | 30 | ||
31 | static inline void ui_progress__delete(struct ui_progress *self __used) {} | 31 | static inline void ui_progress__delete(struct ui_progress *self __used) {} |
32 | #else | 32 | #else |
33 | extern char browser__last_msg[]; | ||
33 | int browser__show_help(const char *format, va_list ap); | 34 | int browser__show_help(const char *format, va_list ap); |
34 | #include "ui/progress.h" | 35 | #include "ui/progress.h" |
35 | #endif | 36 | #endif |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index c0986d342954..f1882589c826 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
@@ -1,16 +1,7 @@ | |||
1 | #define _GNU_SOURCE | 1 | #define _GNU_SOURCE |
2 | #include <stdio.h> | 2 | #include <stdio.h> |
3 | #undef _GNU_SOURCE | 3 | #undef _GNU_SOURCE |
4 | /* | 4 | #include "ui/libslang.h" |
5 | * slang versions <= 2.0.6 have a "#if HAVE_LONG_LONG" that breaks | ||
6 | * the build if it isn't defined. Use the equivalent one that glibc | ||
7 | * has on features.h. | ||
8 | */ | ||
9 | #include <features.h> | ||
10 | #ifndef HAVE_LONG_LONG | ||
11 | #define HAVE_LONG_LONG __GLIBC_HAVE_LONG_LONG | ||
12 | #endif | ||
13 | #include <slang.h> | ||
14 | #include <signal.h> | 5 | #include <signal.h> |
15 | #include <stdlib.h> | 6 | #include <stdlib.h> |
16 | #include <elf.h> | 7 | #include <elf.h> |
@@ -26,17 +17,6 @@ | |||
26 | #include "ui/browser.h" | 17 | #include "ui/browser.h" |
27 | #include "ui/helpline.h" | 18 | #include "ui/helpline.h" |
28 | 19 | ||
29 | #if SLANG_VERSION < 20104 | ||
30 | #define slsmg_printf(msg, args...) SLsmg_printf((char *)msg, ##args) | ||
31 | #define slsmg_write_nstring(msg, len) SLsmg_write_nstring((char *)msg, len) | ||
32 | #define sltt_set_color(obj, name, fg, bg) SLtt_set_color(obj,(char *)name,\ | ||
33 | (char *)fg, (char *)bg) | ||
34 | #else | ||
35 | #define slsmg_printf SLsmg_printf | ||
36 | #define slsmg_write_nstring SLsmg_write_nstring | ||
37 | #define sltt_set_color SLtt_set_color | ||
38 | #endif | ||
39 | |||
40 | newtComponent newt_form__new(void); | 20 | newtComponent newt_form__new(void); |
41 | 21 | ||
42 | static int ui_entry__read(const char *title, char *bf, size_t size, int width) | 22 | static int ui_entry__read(const char *title, char *bf, size_t size, int width) |
@@ -72,7 +52,7 @@ out_free_form: | |||
72 | return 0; | 52 | return 0; |
73 | } | 53 | } |
74 | 54 | ||
75 | static char browser__last_msg[1024]; | 55 | char browser__last_msg[1024]; |
76 | 56 | ||
77 | int browser__show_help(const char *format, va_list ap) | 57 | int browser__show_help(const char *format, va_list ap) |
78 | { | 58 | { |
@@ -192,66 +172,6 @@ static bool dialog_yesno(const char *msg) | |||
192 | return newtWinChoice(NULL, yes, no, (char *)msg) == 1; | 172 | return newtWinChoice(NULL, yes, no, (char *)msg) == 1; |
193 | } | 173 | } |
194 | 174 | ||
195 | static void ui__error_window(const char *fmt, ...) | ||
196 | { | ||
197 | va_list ap; | ||
198 | |||
199 | va_start(ap, fmt); | ||
200 | newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap); | ||
201 | va_end(ap); | ||
202 | } | ||
203 | |||
204 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) | ||
205 | { | ||
206 | struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); | ||
207 | bool current_entry = ui_browser__is_current_entry(self, row); | ||
208 | int width = self->width; | ||
209 | |||
210 | if (ol->offset != -1) { | ||
211 | struct hist_entry *he = self->priv; | ||
212 | struct symbol *sym = he->ms.sym; | ||
213 | int len = he->ms.sym->end - he->ms.sym->start; | ||
214 | unsigned int hits = 0; | ||
215 | double percent = 0.0; | ||
216 | int color; | ||
217 | struct sym_priv *priv = symbol__priv(sym); | ||
218 | struct sym_ext *sym_ext = priv->ext; | ||
219 | struct sym_hist *h = priv->hist; | ||
220 | s64 offset = ol->offset; | ||
221 | struct objdump_line *next = objdump__get_next_ip_line(self->entries, ol); | ||
222 | |||
223 | while (offset < (s64)len && | ||
224 | (next == NULL || offset < next->offset)) { | ||
225 | if (sym_ext) { | ||
226 | percent += sym_ext[offset].percent; | ||
227 | } else | ||
228 | hits += h->ip[offset]; | ||
229 | |||
230 | ++offset; | ||
231 | } | ||
232 | |||
233 | if (sym_ext == NULL && h->sum) | ||
234 | percent = 100.0 * hits / h->sum; | ||
235 | |||
236 | color = ui_browser__percent_color(percent, current_entry); | ||
237 | SLsmg_set_color(color); | ||
238 | slsmg_printf(" %7.2f ", percent); | ||
239 | if (!current_entry) | ||
240 | SLsmg_set_color(HE_COLORSET_CODE); | ||
241 | } else { | ||
242 | int color = ui_browser__percent_color(0, current_entry); | ||
243 | SLsmg_set_color(color); | ||
244 | slsmg_write_nstring(" ", 9); | ||
245 | } | ||
246 | |||
247 | SLsmg_write_char(':'); | ||
248 | slsmg_write_nstring(" ", 8); | ||
249 | if (!*ol->line) | ||
250 | slsmg_write_nstring(" ", width - 18); | ||
251 | else | ||
252 | slsmg_write_nstring(ol->line, width - 18); | ||
253 | } | ||
254 | |||
255 | static char *callchain_list__sym_name(struct callchain_list *self, | 175 | static char *callchain_list__sym_name(struct callchain_list *self, |
256 | char *bf, size_t bfsize) | 176 | char *bf, size_t bfsize) |
257 | { | 177 | { |
@@ -262,54 +182,6 @@ static char *callchain_list__sym_name(struct callchain_list *self, | |||
262 | return bf; | 182 | return bf; |
263 | } | 183 | } |
264 | 184 | ||
265 | int hist_entry__tui_annotate(struct hist_entry *self) | ||
266 | { | ||
267 | struct newtExitStruct es; | ||
268 | struct objdump_line *pos, *n; | ||
269 | LIST_HEAD(head); | ||
270 | struct ui_browser browser = { | ||
271 | .entries = &head, | ||
272 | .refresh = ui_browser__list_head_refresh, | ||
273 | .seek = ui_browser__list_head_seek, | ||
274 | .write = annotate_browser__write, | ||
275 | .priv = self, | ||
276 | }; | ||
277 | int ret; | ||
278 | |||
279 | if (self->ms.sym == NULL) | ||
280 | return -1; | ||
281 | |||
282 | if (self->ms.map->dso->annotate_warned) | ||
283 | return -1; | ||
284 | |||
285 | if (hist_entry__annotate(self, &head) < 0) { | ||
286 | ui__error_window(browser__last_msg); | ||
287 | return -1; | ||
288 | } | ||
289 | |||
290 | ui_helpline__push("Press <- or ESC to exit"); | ||
291 | |||
292 | list_for_each_entry(pos, &head, node) { | ||
293 | size_t line_len = strlen(pos->line); | ||
294 | if (browser.width < line_len) | ||
295 | browser.width = line_len; | ||
296 | ++browser.nr_entries; | ||
297 | } | ||
298 | |||
299 | browser.width += 18; /* Percentage */ | ||
300 | ui_browser__show(&browser, self->ms.sym->name); | ||
301 | newtFormAddHotKey(browser.form, ' '); | ||
302 | ret = ui_browser__run(&browser, &es); | ||
303 | newtFormDestroy(browser.form); | ||
304 | newtPopWindow(); | ||
305 | list_for_each_entry_safe(pos, n, &head, node) { | ||
306 | list_del(&pos->node); | ||
307 | objdump_line__free(pos); | ||
308 | } | ||
309 | ui_helpline__pop(); | ||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | /* -------------------------------------------------------------------- */ | 185 | /* -------------------------------------------------------------------- */ |
314 | 186 | ||
315 | struct map_browser { | 187 | struct map_browser { |
diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h index 8eed24cf2854..856e34361729 100644 --- a/tools/perf/util/ui/browser.h +++ b/tools/perf/util/ui/browser.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <stdbool.h> | 4 | #include <stdbool.h> |
5 | #include <newt.h> | 5 | #include <newt.h> |
6 | #include <sys/types.h> | ||
6 | #include "../types.h" | 7 | #include "../types.h" |
7 | 8 | ||
8 | #define HE_COLORSET_TOP 50 | 9 | #define HE_COLORSET_TOP 50 |
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c new file mode 100644 index 000000000000..783d277f2190 --- /dev/null +++ b/tools/perf/util/ui/browsers/annotate.c | |||
@@ -0,0 +1,114 @@ | |||
1 | #include "../browser.h" | ||
2 | #include "../helpline.h" | ||
3 | #include "../libslang.h" | ||
4 | #include "../../hist.h" | ||
5 | #include "../../sort.h" | ||
6 | #include "../../symbol.h" | ||
7 | |||
8 | static void ui__error_window(const char *fmt, ...) | ||
9 | { | ||
10 | va_list ap; | ||
11 | |||
12 | va_start(ap, fmt); | ||
13 | newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap); | ||
14 | va_end(ap); | ||
15 | } | ||
16 | |||
17 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) | ||
18 | { | ||
19 | struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); | ||
20 | bool current_entry = ui_browser__is_current_entry(self, row); | ||
21 | int width = self->width; | ||
22 | |||
23 | if (ol->offset != -1) { | ||
24 | struct hist_entry *he = self->priv; | ||
25 | struct symbol *sym = he->ms.sym; | ||
26 | int len = he->ms.sym->end - he->ms.sym->start; | ||
27 | unsigned int hits = 0; | ||
28 | double percent = 0.0; | ||
29 | int color; | ||
30 | struct sym_priv *priv = symbol__priv(sym); | ||
31 | struct sym_ext *sym_ext = priv->ext; | ||
32 | struct sym_hist *h = priv->hist; | ||
33 | s64 offset = ol->offset; | ||
34 | struct objdump_line *next = objdump__get_next_ip_line(self->entries, ol); | ||
35 | |||
36 | while (offset < (s64)len && | ||
37 | (next == NULL || offset < next->offset)) { | ||
38 | if (sym_ext) { | ||
39 | percent += sym_ext[offset].percent; | ||
40 | } else | ||
41 | hits += h->ip[offset]; | ||
42 | |||
43 | ++offset; | ||
44 | } | ||
45 | |||
46 | if (sym_ext == NULL && h->sum) | ||
47 | percent = 100.0 * hits / h->sum; | ||
48 | |||
49 | color = ui_browser__percent_color(percent, current_entry); | ||
50 | SLsmg_set_color(color); | ||
51 | slsmg_printf(" %7.2f ", percent); | ||
52 | if (!current_entry) | ||
53 | SLsmg_set_color(HE_COLORSET_CODE); | ||
54 | } else { | ||
55 | int color = ui_browser__percent_color(0, current_entry); | ||
56 | SLsmg_set_color(color); | ||
57 | slsmg_write_nstring(" ", 9); | ||
58 | } | ||
59 | |||
60 | SLsmg_write_char(':'); | ||
61 | slsmg_write_nstring(" ", 8); | ||
62 | if (!*ol->line) | ||
63 | slsmg_write_nstring(" ", width - 18); | ||
64 | else | ||
65 | slsmg_write_nstring(ol->line, width - 18); | ||
66 | } | ||
67 | |||
68 | int hist_entry__tui_annotate(struct hist_entry *self) | ||
69 | { | ||
70 | struct newtExitStruct es; | ||
71 | struct objdump_line *pos, *n; | ||
72 | LIST_HEAD(head); | ||
73 | struct ui_browser browser = { | ||
74 | .entries = &head, | ||
75 | .refresh = ui_browser__list_head_refresh, | ||
76 | .seek = ui_browser__list_head_seek, | ||
77 | .write = annotate_browser__write, | ||
78 | .priv = self, | ||
79 | }; | ||
80 | int ret; | ||
81 | |||
82 | if (self->ms.sym == NULL) | ||
83 | return -1; | ||
84 | |||
85 | if (self->ms.map->dso->annotate_warned) | ||
86 | return -1; | ||
87 | |||
88 | if (hist_entry__annotate(self, &head) < 0) { | ||
89 | ui__error_window(browser__last_msg); | ||
90 | return -1; | ||
91 | } | ||
92 | |||
93 | ui_helpline__push("Press <- or ESC to exit"); | ||
94 | |||
95 | list_for_each_entry(pos, &head, node) { | ||
96 | size_t line_len = strlen(pos->line); | ||
97 | if (browser.width < line_len) | ||
98 | browser.width = line_len; | ||
99 | ++browser.nr_entries; | ||
100 | } | ||
101 | |||
102 | browser.width += 18; /* Percentage */ | ||
103 | ui_browser__show(&browser, self->ms.sym->name); | ||
104 | newtFormAddHotKey(browser.form, ' '); | ||
105 | ret = ui_browser__run(&browser, &es); | ||
106 | newtFormDestroy(browser.form); | ||
107 | newtPopWindow(); | ||
108 | list_for_each_entry_safe(pos, n, &head, node) { | ||
109 | list_del(&pos->node); | ||
110 | objdump_line__free(pos); | ||
111 | } | ||
112 | ui_helpline__pop(); | ||
113 | return ret; | ||
114 | } | ||
diff --git a/tools/perf/util/ui/libslang.h b/tools/perf/util/ui/libslang.h new file mode 100644 index 000000000000..5623da8e8080 --- /dev/null +++ b/tools/perf/util/ui/libslang.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef _PERF_UI_SLANG_H_ | ||
2 | #define _PERF_UI_SLANG_H_ 1 | ||
3 | /* | ||
4 | * slang versions <= 2.0.6 have a "#if HAVE_LONG_LONG" that breaks | ||
5 | * the build if it isn't defined. Use the equivalent one that glibc | ||
6 | * has on features.h. | ||
7 | */ | ||
8 | #include <features.h> | ||
9 | #ifndef HAVE_LONG_LONG | ||
10 | #define HAVE_LONG_LONG __GLIBC_HAVE_LONG_LONG | ||
11 | #endif | ||
12 | #include <slang.h> | ||
13 | |||
14 | #if SLANG_VERSION < 20104 | ||
15 | #define slsmg_printf(msg, args...) \ | ||
16 | SLsmg_printf((char *)msg, ##args) | ||
17 | #define slsmg_write_nstring(msg, len) \ | ||
18 | SLsmg_write_nstring((char *)msg, len) | ||
19 | #define sltt_set_color(obj, name, fg, bg) \ | ||
20 | SLtt_set_color(obj,(char *)name, (char *)fg, (char *)bg) | ||
21 | #else | ||
22 | #define slsmg_printf SLsmg_printf | ||
23 | #define slsmg_write_nstring SLsmg_write_nstring | ||
24 | #define sltt_set_color SLtt_set_color | ||
25 | #endif | ||
26 | |||
27 | #endif /* _PERF_UI_SLANG_H_ */ | ||