summaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-05-22 11:25:40 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-05-22 11:25:40 -0300
commit46e3e055ce69a00d735e458445ab1d24718ff751 (patch)
tree06829420acf27f2deb05ac6ccc230268bf271318 /tools/perf/util
parent6e78c9fd1bc2c7e04b3d7052e9eb27aa536e4e2c (diff)
downloadlinux-46e3e055ce69a00d735e458445ab1d24718ff751.tar.gz
linux-46e3e055ce69a00d735e458445ab1d24718ff751.tar.bz2
linux-46e3e055ce69a00d735e458445ab1d24718ff751.zip
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)
char *filename = dso__build_id_filename(dso, NULL, 0);
char command[PATH_MAX * 2];
FILE *file;
- int err = -1;
+ int err = 0;
u64 len;
if (filename == NULL) {
if (dso->has_build_id) {
pr_err("Can't annotate %s: not enough memory\n",
sym->name);
- return -1;
+ return -ENOMEM;
}
/*
* 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)
}
if (dso->origin == DSO__ORIG_KERNEL) {
- if (dso->annotate_warned) {
- err = 0;
+ if (dso->annotate_warned)
goto out_free_filename;
- }
+ err = -ENOENT;
dso->annotate_warned = 1;
pr_err("Can't annotate %s: No vmlinux file was found in the "
- "path:\n", sym->name);
- vmlinux_path__fprintf(stderr);
+ "path\n", sym->name);
goto out_free_filename;
}
@@ -1046,7 +1044,6 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
break;
pclose(file);
- err = 0;
out_free_filename:
if (dso->has_build_id)
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,
{
return 0;
}
+static inline int hist_entry__tui_annotate(struct hist_entry *self __used)
+{
+ return 0;
+}
+#define KEY_LEFT -1
+#define KEY_RIGHT -2
#else
+#include <newt.h>
int hists__browse(struct hists *self, const char *helpline,
const char *input_name);
+int hist_entry__tui_annotate(struct hist_entry *self);
+#define KEY_LEFT NEWT_KEY_LEFT
+#define KEY_RIGHT NEWT_KEY_RIGHT
#endif
#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)
return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
}
+static void ui__error_window(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap);
+ va_end(ap);
+}
+
#define HE_COLORSET_TOP 50
#define HE_COLORSET_MEDIUM 51
#define HE_COLORSET_NORMAL 52
@@ -386,6 +395,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
newtFormAddHotKey(self->form, ' ');
newtFormAddHotKey(self->form, NEWT_KEY_HOME);
newtFormAddHotKey(self->form, NEWT_KEY_END);
+ newtFormAddHotKey(self->form, NEWT_KEY_TAB);
+ newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
if (ui_browser__refresh_entries(self) < 0)
return -1;
@@ -398,6 +409,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
if (es->reason != NEWT_EXIT_HOTKEY)
break;
+ if (is_exit_key(es->u.key))
+ return es->u.key;
switch (es->u.key) {
case NEWT_KEY_DOWN:
if (self->index == self->nr_entries - 1)
@@ -471,12 +484,10 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
}
}
break;
- case NEWT_KEY_ESCAPE:
+ case NEWT_KEY_RIGHT:
case NEWT_KEY_LEFT:
- case CTRL('c'):
- case 'Q':
- case 'q':
- return 0;
+ case NEWT_KEY_TAB:
+ return es->u.key;
default:
continue;
}
@@ -668,18 +679,24 @@ static size_t hist_entry__append_browser(struct hist_entry *self,
return ret;
}
-static void hist_entry__annotate_browser(struct hist_entry *self)
+int hist_entry__tui_annotate(struct hist_entry *self)
{
struct ui_browser browser;
struct newtExitStruct es;
struct objdump_line *pos, *n;
LIST_HEAD(head);
+ int ret;
if (self->ms.sym == NULL)
- return;
+ return -1;
- if (hist_entry__annotate(self, &head) < 0)
- return;
+ if (self->ms.map->dso->annotate_warned)
+ return -1;
+
+ if (hist_entry__annotate(self, &head) < 0) {
+ ui__error_window(browser__last_msg);
+ return -1;
+ }
ui_helpline__push("Press <- or ESC to exit");
@@ -694,7 +711,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
}
browser.width += 18; /* Percentage */
- ui_browser__run(&browser, self->ms.sym->name, &es);
+ ret = ui_browser__run(&browser, self->ms.sym->name, &es);
newtFormDestroy(browser.form);
newtPopWindow();
list_for_each_entry_safe(pos, n, &head, node) {
@@ -702,6 +719,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
objdump_line__free(pos);
}
ui_helpline__pop();
+ return ret;
}
static const void *newt__symbol_tree_get_current(newtComponent self)
@@ -935,14 +953,14 @@ do_help:
continue;
default:;
}
- if (toupper(es.u.key) == 'Q' ||
- es.u.key == CTRL('c'))
- break;
- if (es.u.key == NEWT_KEY_ESCAPE) {
- if (dialog_yesno("Do you really want to exit?"))
+ if (is_exit_key(es.u.key)) {
+ if (es.u.key == NEWT_KEY_ESCAPE) {
+ if (dialog_yesno("Do you really want to exit?"))
+ break;
+ else
+ continue;
+ } else
break;
- else
- continue;
}
if (es.u.key == NEWT_KEY_LEFT) {
@@ -1006,7 +1024,7 @@ do_annotate:
if (he == NULL)
continue;
- hist_entry__annotate_browser(he);
+ hist_entry__tui_annotate(he);
} else if (choice == zoom_dso) {
zoom_dso:
if (dso_filter) {
@@ -1074,7 +1092,7 @@ void setup_browser(void)
{
struct newtPercentTreeColors *c = &defaultPercentTreeColors;
- if (!isatty(1) || !use_browser) {
+ if (!isatty(1) || !use_browser || dump_trace) {
setup_pager();
return;
}
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 @@
#include <inttypes.h>
#include "../../../include/linux/magic.h"
#include "types.h"
-
+#include <sys/ttydefaults.h>
#ifndef NO_ICONV
#include <iconv.h>
@@ -263,6 +263,19 @@ bool strglobmatch(const char *str, const char *pat);
bool strlazymatch(const char *str, const char *pat);
unsigned long convert_unit(unsigned long value, char *unit);
+#ifndef ESC
+#define ESC 27
+#endif
+
+static inline bool is_exit_key(int key)
+{
+ char up;
+ if (key == CTRL('c') || key == ESC)
+ return true;
+ up = toupper(key);
+ return up == 'Q';
+}
+
#define _STR(x) #x
#define STR(x) _STR(x)