Commit 2b676bf0 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

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: default avatarNamhyung 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.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e3a34029
...@@ -61,11 +61,13 @@ OPTIONS ...@@ -61,11 +61,13 @@ OPTIONS
--stdio:: Use the stdio interface. --stdio:: Use the stdio interface.
--tui:: Use the TUI interface Use of --tui requires a tty, if one is not --tui:: Use the TUI interface. Use of --tui requires a tty, if one is not
present, as when piping to other commands, the stdio interface is present, as when piping to other commands, the stdio interface is
used. This interfaces starts by centering on the line with more used. This interfaces starts by centering on the line with more
samples, TAB/UNTAB cycles through the lines with more samples. samples, TAB/UNTAB cycles through the lines with more samples.
--gtk:: Use the GTK interface.
-C:: -C::
--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can --cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can
be provided as a comma-separated list with no space: 0,1. Ranges of be provided as a comma-separated list with no space: 0,1. Ranges of
......
...@@ -698,6 +698,7 @@ ifndef NO_GTK2 ...@@ -698,6 +698,7 @@ ifndef NO_GTK2
LIB_OBJS += $(OUTPUT)ui/gtk/util.o LIB_OBJS += $(OUTPUT)ui/gtk/util.o
LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
LIB_OBJS += $(OUTPUT)ui/gtk/progress.o LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
endif endif
endif endif
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
struct perf_annotate { struct perf_annotate {
struct perf_tool tool; struct perf_tool tool;
bool force, use_tui, use_stdio; bool force, use_tui, use_stdio, use_gtk;
bool full_paths; bool full_paths;
bool print_line; bool print_line;
const char *sym_hist_filter; const char *sym_hist_filter;
...@@ -138,7 +138,10 @@ static void hists__find_annotations(struct hists *self, int evidx, ...@@ -138,7 +138,10 @@ static void hists__find_annotations(struct hists *self, int evidx,
continue; continue;
} }
if (use_browser > 0) { if (use_browser == 2) {
hist_entry__gtk_annotate(he, evidx, NULL);
return;
} else if (use_browser == 1) {
key = hist_entry__tui_annotate(he, evidx, NULL); key = hist_entry__tui_annotate(he, evidx, NULL);
switch (key) { switch (key) {
case K_RIGHT: case K_RIGHT:
...@@ -270,6 +273,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -270,6 +273,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
"be more verbose (show symbol address, etc)"), "be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"), "dump raw trace in ASCII"),
OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"), OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"),
OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"), OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"),
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 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,6 +304,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
use_browser = 0; use_browser = 0;
else if (annotate.use_tui) else if (annotate.use_tui)
use_browser = 1; use_browser = 1;
else if (annotate.use_gtk)
use_browser = 2;
setup_browser(true); setup_browser(true);
......
#include "gtk.h"
#include "util/debug.h"
#include "util/annotate.h"
#include "ui/helpline.h"
enum {
ANN_COL__PERCENT,
ANN_COL__OFFSET,
ANN_COL__LINE,
MAX_ANN_COLS
};
static const char *const col_names[] = {
"Overhead",
"Offset",
"Line"
};
static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym,
struct disasm_line *dl, int evidx)
{
struct sym_hist *symhist;
double percent = 0.0;
const char *markup;
int ret = 0;
strcpy(buf, "");
if (dl->offset == (s64) -1)
return 0;
symhist = annotation__histogram(symbol__annotation(sym), evidx);
if (!symhist->addr[dl->offset])
return 0;
percent = 100.0 * symhist->addr[dl->offset] / symhist->sum;
markup = perf_gtk__get_percent_color(percent);
if (markup)
ret += scnprintf(buf, size, "%s", markup);
ret += scnprintf(buf + ret, size - ret, "%6.2f%%", percent);
if (markup)
ret += scnprintf(buf + ret, size - ret, "</span>");
return ret;
}
static int perf_gtk__get_offset(char *buf, size_t size, struct symbol *sym,
struct map *map, struct disasm_line *dl)
{
u64 start = map__rip_2objdump(map, sym->start);
strcpy(buf, "");
if (dl->offset == (s64) -1)
return 0;
return scnprintf(buf, size, "%"PRIx64, start + dl->offset);
}
static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
struct map *map, int evidx,
struct hist_browser_timer *hbt __maybe_unused)
{
struct disasm_line *pos, *n;
struct annotation *notes;
GType col_types[MAX_ANN_COLS];
GtkCellRenderer *renderer;
GtkListStore *store;
GtkWidget *view;
int i;
char s[512];
if (map->dso->annotate_warned)
return -1;
if (symbol__annotate(sym, map, 0) < 0) {
ui__error("%s", ui_helpline__current);
return -1;
}
notes = symbol__annotation(sym);
for (i = 0; i < MAX_ANN_COLS; i++) {
col_types[i] = G_TYPE_STRING;
}
store = gtk_list_store_newv(MAX_ANN_COLS, col_types);
view = gtk_tree_view_new();
renderer = gtk_cell_renderer_text_new();
for (i = 0; i < MAX_ANN_COLS; i++) {
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
-1, col_names[i], renderer,
i == ANN_COL__PERCENT ? "markup" : "text",
i, NULL);
}
gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
g_object_unref(GTK_TREE_MODEL(store));
list_for_each_entry(pos, &notes->src->source, node) {
GtkTreeIter iter;
gtk_list_store_append(store, &iter);
if (perf_gtk__get_percent(s, sizeof(s), sym, pos, evidx))
gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1);
if (perf_gtk__get_offset(s, sizeof(s), sym, map, pos))
gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1);
gtk_list_store_set(store, &iter, ANN_COL__LINE, pos->line, -1);
}
gtk_container_add(GTK_CONTAINER(window), view);
list_for_each_entry_safe(pos, n, &notes->src->source, node) {
list_del(&pos->node);
disasm_line__free(pos);
}
return 0;
}
int symbol__gtk_annotate(struct symbol *sym, struct map *map, int evidx,
struct hist_browser_timer *hbt)
{
GtkWidget *vbox;
GtkWidget *notebook;
GtkWidget *infobar;
GtkWidget *statbar;
GtkWidget *window;
GtkWidget *scrolled_window;
GtkWidget *tab_label;
signal(SIGSEGV, perf_gtk__signal);
signal(SIGFPE, perf_gtk__signal);
signal(SIGINT, perf_gtk__signal);
signal(SIGQUIT, perf_gtk__signal);
signal(SIGTERM, perf_gtk__signal);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "perf annotate");
g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
pgctx = perf_gtk__activate_context(window);
if (!pgctx)
return -1;
vbox = gtk_vbox_new(FALSE, 0);
notebook = gtk_notebook_new();
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
tab_label = gtk_label_new(sym->name);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window,
tab_label);
gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
infobar = perf_gtk__setup_info_bar();
if (infobar)
gtk_box_pack_start(GTK_BOX(vbox), infobar, FALSE, FALSE, 0);
statbar = perf_gtk__setup_statusbar();
gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
perf_gtk__annotate_symbol(scrolled_window, sym, map, evidx, hbt);
gtk_widget_show_all(window);
perf_gtk__resize_window(window);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_main();
perf_gtk__deactivate_context(&pgctx);
return 0;
}
...@@ -8,7 +8,7 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; ...@@ -8,7 +8,7 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
void setup_browser(bool fallback_to_pager) void setup_browser(bool fallback_to_pager)
{ {
if (!isatty(1) || dump_trace) if (use_browser < 2 && (!isatty(1) || dump_trace))
use_browser = 0; use_browser = 0;
/* default to TUI */ /* default to TUI */
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "types.h" #include "types.h"
#include "symbol.h" #include "symbol.h"
#include "hist.h" #include "hist.h"
#include "sort.h"
#include <linux/list.h> #include <linux/list.h>
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <pthread.h> #include <pthread.h>
...@@ -154,6 +155,25 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, ...@@ -154,6 +155,25 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
} }
#endif #endif
#ifdef GTK2_SUPPORT
int symbol__gtk_annotate(struct symbol *sym, struct map *map, int evidx,
struct hist_browser_timer *hbt);
static inline int hist_entry__gtk_annotate(struct hist_entry *he, int evidx,
struct hist_browser_timer *hbt)
{
return symbol__gtk_annotate(he->ms.sym, he->ms.map, evidx, hbt);
}
#else
static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
int evidx __maybe_unused,
struct hist_browser_timer *hbt
__maybe_unused)
{
return 0;
}
#endif
extern const char *disassembler_style; extern const char *disassembler_style;
#endif /* __PERF_ANNOTATE_H */ #endif /* __PERF_ANNOTATE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment