aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-05-22 10:25:40 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-05-22 10:25:40 -0400
commit46e3e055ce69a00d735e458445ab1d24718ff751 (patch)
tree06829420acf27f2deb05ac6ccc230268bf271318 /tools/perf/util
parent6e78c9fd1bc2c7e04b3d7052e9eb27aa536e4e2c (diff)
perf annotate: Add TUI interface
When annotating multiple entries, for instance, when running simply as: $ perf annotate the right and left keys, as well as TAB can be used to cycle thru the multiple symbols being annotated. If one doesn't like TUI annotate, disable it by editing ~/.perfconfig and adding: [tui] annotate = off Just like it is possible for report. 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')
-rw-r--r--tools/perf/util/hist.c13
-rw-r--r--tools/perf/util/hist.h10
-rw-r--r--tools/perf/util/newt.c56
-rw-r--r--tools/perf/util/util.h15
4 files changed, 66 insertions, 28 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 009ad76b0879..682a6d88862c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -992,14 +992,14 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
992 char *filename = dso__build_id_filename(dso, NULL, 0); 992 char *filename = dso__build_id_filename(dso, NULL, 0);
993 char command[PATH_MAX * 2]; 993 char command[PATH_MAX * 2];
994 FILE *file; 994 FILE *file;
995 int err = -1; 995 int err = 0;
996 u64 len; 996 u64 len;
997 997
998 if (filename == NULL) { 998 if (filename == NULL) {
999 if (dso->has_build_id) { 999 if (dso->has_build_id) {
1000 pr_err("Can't annotate %s: not enough memory\n", 1000 pr_err("Can't annotate %s: not enough memory\n",
1001 sym->name); 1001 sym->name);
1002 return -1; 1002 return -ENOMEM;
1003 } 1003 }
1004 /* 1004 /*
1005 * If we don't have build-ids, well, lets hope that this 1005 * If we don't have build-ids, well, lets hope that this
@@ -1009,14 +1009,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
1009 } 1009 }
1010 1010
1011 if (dso->origin == DSO__ORIG_KERNEL) { 1011 if (dso->origin == DSO__ORIG_KERNEL) {
1012 if (dso->annotate_warned) { 1012 if (dso->annotate_warned)
1013 err = 0;
1014 goto out_free_filename; 1013 goto out_free_filename;
1015 } 1014 err = -ENOENT;
1016 dso->annotate_warned = 1; 1015 dso->annotate_warned = 1;
1017 pr_err("Can't annotate %s: No vmlinux file was found in the " 1016 pr_err("Can't annotate %s: No vmlinux file was found in the "
1018 "path:\n", sym->name); 1017 "path\n", sym->name);
1019 vmlinux_path__fprintf(stderr);
1020 goto out_free_filename; 1018 goto out_free_filename;
1021 } 1019 }
1022 1020
@@ -1046,7 +1044,6 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
1046 break; 1044 break;
1047 1045
1048 pclose(file); 1046 pclose(file);
1049 err = 0;
1050out_free_filename: 1047out_free_filename:
1051 if (dso->has_build_id) 1048 if (dso->has_build_id)
1052 free(filename); 1049 free(filename);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 6f17dcd8412c..2d5203fedb20 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -102,8 +102,18 @@ static inline int hists__browse(struct hists *self __used,
102{ 102{
103 return 0; 103 return 0;
104} 104}
105static inline int hist_entry__tui_annotate(struct hist_entry *self __used)
106{
107 return 0;
108}
109#define KEY_LEFT -1
110#define KEY_RIGHT -2
105#else 111#else
112#include <newt.h>
106int hists__browse(struct hists *self, const char *helpline, 113int hists__browse(struct hists *self, const char *helpline,
107 const char *input_name); 114 const char *input_name);
115int hist_entry__tui_annotate(struct hist_entry *self);
116#define KEY_LEFT NEWT_KEY_LEFT
117#define KEY_RIGHT NEWT_KEY_RIGHT
108#endif 118#endif
109#endif /* __PERF_HIST_H */ 119#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index c65838c99354..ffd04720b754 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -235,6 +235,15 @@ static bool dialog_yesno(const char *msg)
235 return newtWinChoice(NULL, yes, no, (char *)msg) == 1; 235 return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
236} 236}
237 237
238static void ui__error_window(const char *fmt, ...)
239{
240 va_list ap;
241
242 va_start(ap, fmt);
243 newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap);
244 va_end(ap);
245}
246
238#define HE_COLORSET_TOP 50 247#define HE_COLORSET_TOP 50
239#define HE_COLORSET_MEDIUM 51 248#define HE_COLORSET_MEDIUM 51
240#define HE_COLORSET_NORMAL 52 249#define HE_COLORSET_NORMAL 52
@@ -386,6 +395,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
386 newtFormAddHotKey(self->form, ' '); 395 newtFormAddHotKey(self->form, ' ');
387 newtFormAddHotKey(self->form, NEWT_KEY_HOME); 396 newtFormAddHotKey(self->form, NEWT_KEY_HOME);
388 newtFormAddHotKey(self->form, NEWT_KEY_END); 397 newtFormAddHotKey(self->form, NEWT_KEY_END);
398 newtFormAddHotKey(self->form, NEWT_KEY_TAB);
399 newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
389 400
390 if (ui_browser__refresh_entries(self) < 0) 401 if (ui_browser__refresh_entries(self) < 0)
391 return -1; 402 return -1;
@@ -398,6 +409,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
398 409
399 if (es->reason != NEWT_EXIT_HOTKEY) 410 if (es->reason != NEWT_EXIT_HOTKEY)
400 break; 411 break;
412 if (is_exit_key(es->u.key))
413 return es->u.key;
401 switch (es->u.key) { 414 switch (es->u.key) {
402 case NEWT_KEY_DOWN: 415 case NEWT_KEY_DOWN:
403 if (self->index == self->nr_entries - 1) 416 if (self->index == self->nr_entries - 1)
@@ -471,12 +484,10 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
471 } 484 }
472 } 485 }
473 break; 486 break;
474 case NEWT_KEY_ESCAPE: 487 case NEWT_KEY_RIGHT:
475 case NEWT_KEY_LEFT: 488 case NEWT_KEY_LEFT:
476 case CTRL('c'): 489 case NEWT_KEY_TAB:
477 case 'Q': 490 return es->u.key;
478 case 'q':
479 return 0;
480 default: 491 default:
481 continue; 492 continue;
482 } 493 }
@@ -668,18 +679,24 @@ static size_t hist_entry__append_browser(struct hist_entry *self,
668 return ret; 679 return ret;
669} 680}
670 681
671static void hist_entry__annotate_browser(struct hist_entry *self) 682int hist_entry__tui_annotate(struct hist_entry *self)
672{ 683{
673 struct ui_browser browser; 684 struct ui_browser browser;
674 struct newtExitStruct es; 685 struct newtExitStruct es;
675 struct objdump_line *pos, *n; 686 struct objdump_line *pos, *n;
676 LIST_HEAD(head); 687 LIST_HEAD(head);
688 int ret;
677 689
678 if (self->ms.sym == NULL) 690 if (self->ms.sym == NULL)
679 return; 691 return -1;
680 692
681 if (hist_entry__annotate(self, &head) < 0) 693 if (self->ms.map->dso->annotate_warned)
682 return; 694 return -1;
695
696 if (hist_entry__annotate(self, &head) < 0) {
697 ui__error_window(browser__last_msg);
698 return -1;
699 }
683 700
684 ui_helpline__push("Press <- or ESC to exit"); 701 ui_helpline__push("Press <- or ESC to exit");
685 702
@@ -694,7 +711,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
694 } 711 }
695 712
696 browser.width += 18; /* Percentage */ 713 browser.width += 18; /* Percentage */
697 ui_browser__run(&browser, self->ms.sym->name, &es); 714 ret = ui_browser__run(&browser, self->ms.sym->name, &es);
698 newtFormDestroy(browser.form); 715 newtFormDestroy(browser.form);
699 newtPopWindow(); 716 newtPopWindow();
700 list_for_each_entry_safe(pos, n, &head, node) { 717 list_for_each_entry_safe(pos, n, &head, node) {
@@ -702,6 +719,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
702 objdump_line__free(pos); 719 objdump_line__free(pos);
703 } 720 }
704 ui_helpline__pop(); 721 ui_helpline__pop();
722 return ret;
705} 723}
706 724
707static const void *newt__symbol_tree_get_current(newtComponent self) 725static const void *newt__symbol_tree_get_current(newtComponent self)
@@ -935,14 +953,14 @@ do_help:
935 continue; 953 continue;
936 default:; 954 default:;
937 } 955 }
938 if (toupper(es.u.key) == 'Q' || 956 if (is_exit_key(es.u.key)) {
939 es.u.key == CTRL('c')) 957 if (es.u.key == NEWT_KEY_ESCAPE) {
940 break; 958 if (dialog_yesno("Do you really want to exit?"))
941 if (es.u.key == NEWT_KEY_ESCAPE) { 959 break;
942 if (dialog_yesno("Do you really want to exit?")) 960 else
961 continue;
962 } else
943 break; 963 break;
944 else
945 continue;
946 } 964 }
947 965
948 if (es.u.key == NEWT_KEY_LEFT) { 966 if (es.u.key == NEWT_KEY_LEFT) {
@@ -1006,7 +1024,7 @@ do_annotate:
1006 if (he == NULL) 1024 if (he == NULL)
1007 continue; 1025 continue;
1008 1026
1009 hist_entry__annotate_browser(he); 1027 hist_entry__tui_annotate(he);
1010 } else if (choice == zoom_dso) { 1028 } else if (choice == zoom_dso) {
1011zoom_dso: 1029zoom_dso:
1012 if (dso_filter) { 1030 if (dso_filter) {
@@ -1074,7 +1092,7 @@ void setup_browser(void)
1074{ 1092{
1075 struct newtPercentTreeColors *c = &defaultPercentTreeColors; 1093 struct newtPercentTreeColors *c = &defaultPercentTreeColors;
1076 1094
1077 if (!isatty(1) || !use_browser) { 1095 if (!isatty(1) || !use_browser || dump_trace) {
1078 setup_pager(); 1096 setup_pager();
1079 return; 1097 return;
1080 } 1098 }
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 45b9655f3a5c..4e8b6b0c551c 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -81,7 +81,7 @@
81#include <inttypes.h> 81#include <inttypes.h>
82#include "../../../include/linux/magic.h" 82#include "../../../include/linux/magic.h"
83#include "types.h" 83#include "types.h"
84 84#include <sys/ttydefaults.h>
85 85
86#ifndef NO_ICONV 86#ifndef NO_ICONV
87#include <iconv.h> 87#include <iconv.h>
@@ -263,6 +263,19 @@ bool strglobmatch(const char *str, const char *pat);
263bool strlazymatch(const char *str, const char *pat); 263bool strlazymatch(const char *str, const char *pat);
264unsigned long convert_unit(unsigned long value, char *unit); 264unsigned long convert_unit(unsigned long value, char *unit);
265 265
266#ifndef ESC
267#define ESC 27
268#endif
269
270static inline bool is_exit_key(int key)
271{
272 char up;
273 if (key == CTRL('c') || key == ESC)
274 return true;
275 up = toupper(key);
276 return up == 'Q';
277}
278
266#define _STR(x) #x 279#define _STR(x) #x
267#define STR(x) _STR(x) 280#define STR(x) _STR(x)
268 281