From c8fad62a08652c00b7cf2a6429acf5d5fdae3138 Mon Sep 17 00:00:00 2001 From: Geunsik Lim Date: Fri, 12 Aug 2011 14:30:22 +0900 Subject: [PATCH] --- yaml --- r: 269095 b: refs/heads/master c: 9b5f8b31af57a8ce9e9f77864d9143b5e3304815 h: refs/heads/master i: 269093: c082960c31f43c11216ea34d420112333dbfe6a3 269091: 5e865dda03309f5d312fd4fe22ba858e42bd1a9b 269087: 90edcbde0318689ab1dd5c8e1b74261bd4c39754 v: v3 --- [refs] | 2 +- trunk/kernel/trace/trace.c | 4 +- trunk/tools/perf/builtin-top.c | 25 +- trunk/tools/perf/perf.c | 24 -- trunk/tools/perf/perf.h | 2 - trunk/tools/perf/util/header.c | 2 +- trunk/tools/perf/util/hist.c | 24 +- trunk/tools/perf/util/hist.h | 11 +- trunk/tools/perf/util/sort.h | 1 - trunk/tools/perf/util/ui/browser.c | 228 ++++++------------- trunk/tools/perf/util/ui/browser.h | 10 +- trunk/tools/perf/util/ui/browsers/annotate.c | 95 ++------ trunk/tools/perf/util/ui/browsers/hists.c | 110 +++++---- trunk/tools/perf/util/ui/browsers/map.c | 6 +- trunk/tools/perf/util/ui/helpline.h | 2 - 15 files changed, 168 insertions(+), 378 deletions(-) diff --git a/[refs] b/[refs] index fc222e720ccd..726b5dfb0f7c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c73a3cb356f94b443aa7624b539493191dbf44c1 +refs/heads/master: 9b5f8b31af57a8ce9e9f77864d9143b5e3304815 diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index f86efe90ca45..cea16053f553 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -2720,9 +2720,9 @@ static const char readme_msg[] = "# cat /sys/kernel/debug/tracing/trace_options\n" "noprint-parent nosym-offset nosym-addr noverbose\n" "# echo print-parent > /sys/kernel/debug/tracing/trace_options\n" - "# echo 1 > /sys/kernel/debug/tracing/tracing_enabled\n" + "# echo 1 > /sys/kernel/debug/tracing/tracing_on\n" "# cat /sys/kernel/debug/tracing/trace > /tmp/trace.txt\n" - "# echo 0 > /sys/kernel/debug/tracing/tracing_enabled\n" + "# echo 0 > /sys/kernel/debug/tracing/tracing_on\n" ; static ssize_t diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index e211304a0dd7..c5aebf6eb746 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -304,7 +304,7 @@ static void print_sym_table(void) hists__collapse_resort_threaded(&top.sym_evsel->hists); hists__output_resort_threaded(&top.sym_evsel->hists); - hists__decay_entries_threaded(&top.sym_evsel->hists); + hists__decay_entries(&top.sym_evsel->hists); hists__output_recalc_col_len(&top.sym_evsel->hists, winsize.ws_row - 3); putchar('\n'); hists__fprintf(&top.sym_evsel->hists, NULL, false, false, @@ -555,7 +555,7 @@ static void perf_top__sort_new_samples(void *arg) hists__collapse_resort_threaded(&t->sym_evsel->hists); hists__output_resort_threaded(&t->sym_evsel->hists); - hists__decay_entries_threaded(&t->sym_evsel->hists); + hists__decay_entries(&t->sym_evsel->hists); hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3); } @@ -585,31 +585,16 @@ static void *display_thread(void *arg __used) tc.c_cc[VMIN] = 0; tc.c_cc[VTIME] = 0; - pthread__unblock_sigwinch(); repeat: delay_msecs = top.delay_secs * 1000; tcsetattr(0, TCSANOW, &tc); /* trash return*/ getc(stdin); - while (1) { + do { print_sym_table(); - /* - * Either timeout expired or we got an EINTR due to SIGWINCH, - * refresh screen in both cases. - */ - switch (poll(&stdin_poll, 1, delay_msecs)) { - case 0: - continue; - case -1: - if (errno == EINTR) - continue; - /* Fall trhu */ - default: - goto process_hotkey; - } - } -process_hotkey: + } while (!poll(&stdin_poll, 1, delay_msecs) == 1); + c = getc(stdin); tcsetattr(0, TCSAFLUSH, &save); diff --git a/trunk/tools/perf/perf.c b/trunk/tools/perf/perf.c index 73d0cac8b67e..ec635b7cc8ea 100644 --- a/trunk/tools/perf/perf.c +++ b/trunk/tools/perf/perf.c @@ -427,24 +427,6 @@ static void get_debugfs_mntpt(void) debugfs_mntpt[0] = '\0'; } -static void pthread__block_sigwinch(void) -{ - sigset_t set; - - sigemptyset(&set); - sigaddset(&set, SIGWINCH); - pthread_sigmask(SIG_BLOCK, &set, NULL); -} - -void pthread__unblock_sigwinch(void) -{ - sigset_t set; - - sigemptyset(&set); - sigaddset(&set, SIGWINCH); - pthread_sigmask(SIG_UNBLOCK, &set, NULL); -} - int main(int argc, const char **argv) { const char *cmd; @@ -498,12 +480,6 @@ int main(int argc, const char **argv) * time. */ setup_path(); - /* - * Block SIGWINCH notifications so that the thread that wants it can - * unblock and get syscalls like select interrupted instead of waiting - * forever while the signal goes to some other non interested thread. - */ - pthread__block_sigwinch(); while (1) { static int done_help; diff --git a/trunk/tools/perf/perf.h b/trunk/tools/perf/perf.h index 914c895510f7..08b0b5e82a44 100644 --- a/trunk/tools/perf/perf.h +++ b/trunk/tools/perf/perf.h @@ -183,6 +183,4 @@ struct ip_callchain { extern bool perf_host, perf_guest; extern const char perf_version_string[]; -void pthread__unblock_sigwinch(void); - #endif diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 2143a32638c2..f2ceb0f7d669 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -1289,7 +1289,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) if (access(linkname, F_OK)) goto out_free; - if (readlink(linkname, filename, size - 1) < 0) + if (readlink(linkname, filename, size) < 0) goto out_free; if (unlink(linkname)) diff --git a/trunk/tools/perf/util/hist.c b/trunk/tools/perf/util/hist.c index a7193c5a0422..50c8fece1681 100644 --- a/trunk/tools/perf/util/hist.c +++ b/trunk/tools/perf/util/hist.c @@ -100,15 +100,13 @@ static void hist_entry__decay(struct hist_entry *he) static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) { - if (he->period == 0) - return true; hists->stats.total_period -= he->period; hist_entry__decay(he); hists->stats.total_period += he->period; return he->period == 0; } -static void __hists__decay_entries(struct hists *hists, bool threaded) +void hists__decay_entries(struct hists *hists) { struct rb_node *next = rb_first(&hists->entries); struct hist_entry *n; @@ -116,15 +114,11 @@ static void __hists__decay_entries(struct hists *hists, bool threaded) while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - /* - * We may be annotating this, for instance, so keep it here in - * case some it gets new samples, we'll eventually free it when - * the user stops browsing and it agains gets fully decayed. - */ - if (hists__decay_entry(hists, n) && !n->used) { + + if (hists__decay_entry(hists, n)) { rb_erase(&n->rb_node, &hists->entries); - if (sort__need_collapse || threaded) + if (sort__need_collapse) rb_erase(&n->rb_node_in, &hists->entries_collapsed); hist_entry__free(n); @@ -133,16 +127,6 @@ static void __hists__decay_entries(struct hists *hists, bool threaded) } } -void hists__decay_entries(struct hists *hists) -{ - return __hists__decay_entries(hists, false); -} - -void hists__decay_entries_threaded(struct hists *hists) -{ - return __hists__decay_entries(hists, true); -} - /* * histogram, sorted on item, collects periods */ diff --git a/trunk/tools/perf/util/hist.h b/trunk/tools/perf/util/hist.h index bcc8ab91e26f..7ea1e560e008 100644 --- a/trunk/tools/perf/util/hist.h +++ b/trunk/tools/perf/util/hist.h @@ -79,7 +79,6 @@ void hists__collapse_resort(struct hists *self); void hists__collapse_resort_threaded(struct hists *hists); void hists__decay_entries(struct hists *hists); -void hists__decay_entries_threaded(struct hists *hists); void hists__output_recalc_col_len(struct hists *hists, int max_rows); void hists__inc_nr_events(struct hists *self, u32 type); @@ -104,20 +103,16 @@ struct perf_evlist; #ifdef NO_NEWT_SUPPORT static inline int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __used, - const char *help __used, - void(*timer)(void *arg) __used, - void *arg __used, + const char *help __used, void(*timer)(void *arg) __used, void *arg, int refresh __used) { return 0; } static inline int hist_entry__tui_annotate(struct hist_entry *self __used, - int evidx __used, - int nr_events __used, + int evidx __used, int nr_events __used, void(*timer)(void *arg) __used, - void *arg __used, - int delay_secs __used) + void *arg __used, int delay_secs __used); { return 0; } diff --git a/trunk/tools/perf/util/sort.h b/trunk/tools/perf/util/sort.h index 3f67ae395752..03851e301721 100644 --- a/trunk/tools/perf/util/sort.h +++ b/trunk/tools/perf/util/sort.h @@ -64,7 +64,6 @@ struct hist_entry { bool init_have_children; char level; - bool used; u8 filtered; struct symbol *parent; union { diff --git a/trunk/tools/perf/util/ui/browser.c b/trunk/tools/perf/util/ui/browser.c index a54b926efe2b..611219f80680 100644 --- a/trunk/tools/perf/util/ui/browser.c +++ b/trunk/tools/perf/util/ui/browser.c @@ -1,7 +1,4 @@ -#include "../util.h" -#include "../../perf.h" #include "libslang.h" -#include #include "ui.h" #include #include @@ -11,8 +8,8 @@ #include "browser.h" #include "helpline.h" #include "../color.h" - -int newtGetKey(void); +#include "../util.h" +#include static int ui_browser__percent_color(double percent, bool current) { @@ -42,62 +39,31 @@ void ui_browser__gotorc(struct ui_browser *self, int y, int x) SLsmg_gotorc(self->y + y, self->x + x); } -static struct list_head * -ui_browser__list_head_filter_entries(struct ui_browser *browser, - struct list_head *pos) -{ - do { - if (!browser->filter || !browser->filter(browser, pos)) - return pos; - pos = pos->next; - } while (pos != browser->entries); - - return NULL; -} - -static struct list_head * -ui_browser__list_head_filter_prev_entries(struct ui_browser *browser, - struct list_head *pos) -{ - do { - if (!browser->filter || !browser->filter(browser, pos)) - return pos; - pos = pos->prev; - } while (pos != browser->entries); - - return NULL; -} - void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence) { struct list_head *head = self->entries; struct list_head *pos; - if (self->nr_entries == 0) - return; - switch (whence) { case SEEK_SET: - pos = ui_browser__list_head_filter_entries(self, head->next); + pos = head->next; break; case SEEK_CUR: pos = self->top; break; case SEEK_END: - pos = ui_browser__list_head_filter_prev_entries(self, head->prev); + pos = head->prev; break; default: return; } - assert(pos != NULL); - if (offset > 0) { while (offset-- != 0) - pos = ui_browser__list_head_filter_entries(self, pos->next); + pos = pos->next; } else { while (offset++ != 0) - pos = ui_browser__list_head_filter_prev_entries(self, pos->prev); + pos = pos->prev; } self->top = pos; @@ -161,8 +127,11 @@ bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row) void ui_browser__refresh_dimensions(struct ui_browser *self) { - self->width = SLtt_Screen_Cols - 1; - self->height = SLtt_Screen_Rows - 2; + int cols, rows; + newtGetScreenSize(&cols, &rows); + + self->width = cols - 1; + self->height = rows - 2; self->y = 1; self->x = 0; } @@ -173,11 +142,26 @@ void ui_browser__reset_index(struct ui_browser *self) self->seek(self, 0, SEEK_SET); } +void ui_browser__add_exit_key(struct ui_browser *self, int key) +{ + newtFormAddHotKey(self->form, key); +} + +void ui_browser__add_exit_keys(struct ui_browser *self, int keys[]) +{ + int i = 0; + + while (keys[i] && i < 64) { + ui_browser__add_exit_key(self, keys[i]); + ++i; + } +} + void __ui_browser__show_title(struct ui_browser *browser, const char *title) { SLsmg_gotorc(0, 0); ui_browser__set_color(browser, NEWT_COLORSET_ROOT); - slsmg_write_nstring(title, browser->width + 1); + slsmg_write_nstring(title, browser->width); } void ui_browser__show_title(struct ui_browser *browser, const char *title) @@ -190,143 +174,77 @@ void ui_browser__show_title(struct ui_browser *browser, const char *title) int ui_browser__show(struct ui_browser *self, const char *title, const char *helpline, ...) { - int err; va_list ap; + int keys[] = { NEWT_KEY_UP, NEWT_KEY_DOWN, NEWT_KEY_PGUP, + NEWT_KEY_PGDN, NEWT_KEY_HOME, NEWT_KEY_END, ' ', + NEWT_KEY_LEFT, NEWT_KEY_ESCAPE, 'q', CTRL('c'), 0 }; + + if (self->form != NULL) + newtFormDestroy(self->form); ui_browser__refresh_dimensions(self); + self->form = newtForm(NULL, NULL, 0); + if (self->form == NULL) + return -1; + + self->sb = newtVerticalScrollbar(self->width, 1, self->height, + HE_COLORSET_NORMAL, + HE_COLORSET_SELECTED); + if (self->sb == NULL) + return -1; pthread_mutex_lock(&ui__lock); __ui_browser__show_title(self, title); - self->title = title; - free(self->helpline); - self->helpline = NULL; + ui_browser__add_exit_keys(self, keys); + newtFormAddComponent(self->form, self->sb); va_start(ap, helpline); - err = vasprintf(&self->helpline, helpline, ap); + ui_helpline__vpush(helpline, ap); va_end(ap); - if (err > 0) - ui_helpline__push(self->helpline); pthread_mutex_unlock(&ui__lock); - return err ? 0 : -1; + return 0; } -void ui_browser__hide(struct ui_browser *browser __used) +void ui_browser__hide(struct ui_browser *self) { pthread_mutex_lock(&ui__lock); + newtFormDestroy(self->form); + self->form = NULL; ui_helpline__pop(); pthread_mutex_unlock(&ui__lock); } -static void ui_browser__scrollbar_set(struct ui_browser *browser) -{ - int height = browser->height, h = 0, pct = 0, - col = browser->width, - row = browser->y - 1; - - if (browser->nr_entries > 1) { - pct = ((browser->index * (browser->height - 1)) / - (browser->nr_entries - 1)); - } - - while (h < height) { - ui_browser__gotorc(browser, row++, col); - SLsmg_set_char_set(1); - SLsmg_write_char(h == pct ? SLSMG_DIAMOND_CHAR : SLSMG_BOARD_CHAR); - SLsmg_set_char_set(0); - ++h; - } -} - -static int __ui_browser__refresh(struct ui_browser *browser) +int ui_browser__refresh(struct ui_browser *self) { int row; - row = browser->refresh(browser); - ui_browser__set_color(browser, HE_COLORSET_NORMAL); - SLsmg_fill_region(browser->y + row, browser->x, - browser->height - row, browser->width, ' '); - ui_browser__scrollbar_set(browser); - - return 0; -} - -int ui_browser__refresh(struct ui_browser *browser) -{ pthread_mutex_lock(&ui__lock); - __ui_browser__refresh(browser); + newtScrollbarSet(self->sb, self->index, self->nr_entries - 1); + row = self->refresh(self); + ui_browser__set_color(self, HE_COLORSET_NORMAL); + SLsmg_fill_region(self->y + row, self->x, + self->height - row, self->width, ' '); pthread_mutex_unlock(&ui__lock); return 0; } -/* - * Here we're updating nr_entries _after_ we started browsing, i.e. we have to - * forget about any reference to any entry in the underlying data structure, - * that is why we do a SEEK_SET. Think about 'perf top' in the hists browser - * after an output_resort and hist decay. - */ -void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries) -{ - off_t offset = nr_entries - browser->nr_entries; - - browser->nr_entries = nr_entries; - - if (offset < 0) { - if (browser->top_idx < (u64)-offset) - offset = -browser->top_idx; - - browser->index += offset; - browser->top_idx += offset; - } - - browser->top = NULL; - browser->seek(browser, browser->top_idx, SEEK_SET); -} - -int ui_browser__run(struct ui_browser *self, int delay_secs) +int ui_browser__run(struct ui_browser *self) { - int err, key; - struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL; + struct newtExitStruct es; - pthread__unblock_sigwinch(); + if (ui_browser__refresh(self) < 0) + return -1; while (1) { off_t offset; - fd_set read_set; - pthread_mutex_lock(&ui__lock); - err = __ui_browser__refresh(self); - SLsmg_refresh(); - pthread_mutex_unlock(&ui__lock); - if (err < 0) - break; - - FD_ZERO(&read_set); - FD_SET(0, &read_set); - - if (delay_secs) { - timeout.tv_sec = delay_secs; - timeout.tv_usec = 0; - } + newtFormRun(self->form, &es); - err = select(1, &read_set, NULL, NULL, ptimeout); - if (err > 0 && FD_ISSET(0, &read_set)) - key = newtGetKey(); - else if (err == 0) + if (es.reason != NEWT_EXIT_HOTKEY) break; - else { - pthread_mutex_lock(&ui__lock); - SLtt_get_screen_size(); - SLsmg_reinit_smg(); - pthread_mutex_unlock(&ui__lock); - ui_browser__refresh_dimensions(self); - __ui_browser__show_title(self, self->title); - ui_helpline__puts(self->helpline); - continue; - } - - switch (key) { + switch (es.u.key) { case NEWT_KEY_DOWN: if (self->index == self->nr_entries - 1) break; @@ -383,8 +301,10 @@ int ui_browser__run(struct ui_browser *self, int delay_secs) self->seek(self, -offset, SEEK_END); break; default: - return key; + return es.u.key; } + if (ui_browser__refresh(self) < 0) + return -1; } return -1; } @@ -396,29 +316,27 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *self) int row = 0; if (self->top == NULL || self->top == self->entries) - self->top = ui_browser__list_head_filter_entries(self, head->next); + self->top = head->next; pos = self->top; list_for_each_from(pos, head) { - if (!self->filter || !self->filter(self, pos)) { - ui_browser__gotorc(self, row, 0); - self->write(self, pos, row); - if (++row == self->height) - break; - } + ui_browser__gotorc(self, row, 0); + self->write(self, pos, row); + if (++row == self->height) + break; } return row; } -static struct ui_browser__colors { +static struct newtPercentTreeColors { const char *topColorFg, *topColorBg; const char *mediumColorFg, *mediumColorBg; const char *normalColorFg, *normalColorBg; const char *selColorFg, *selColorBg; const char *codeColorFg, *codeColorBg; -} ui_browser__default_colors = { +} defaultPercentTreeColors = { "red", "lightgray", "green", "lightgray", "black", "lightgray", @@ -428,7 +346,7 @@ static struct ui_browser__colors { void ui_browser__init(void) { - struct ui_browser__colors *c = &ui_browser__default_colors; + struct newtPercentTreeColors *c = &defaultPercentTreeColors; sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg); sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg); diff --git a/trunk/tools/perf/util/ui/browser.h b/trunk/tools/perf/util/ui/browser.h index 351c006dd4b5..fc63dda10910 100644 --- a/trunk/tools/perf/util/ui/browser.h +++ b/trunk/tools/perf/util/ui/browser.h @@ -2,6 +2,7 @@ #define _PERF_UI_BROWSER_H_ 1 #include +#include #include #include "../types.h" @@ -12,16 +13,14 @@ #define HE_COLORSET_CODE 54 struct ui_browser { + newtComponent form, sb; u64 index, top_idx; void *top, *entries; u16 y, x, width, height; void *priv; - const char *title; - char *helpline; unsigned int (*refresh)(struct ui_browser *self); void (*write)(struct ui_browser *self, void *entry, int row); void (*seek)(struct ui_browser *self, off_t offset, int whence); - bool (*filter)(struct ui_browser *self, void *entry); u32 nr_entries; }; @@ -33,14 +32,15 @@ void ui_browser__refresh_dimensions(struct ui_browser *self); void ui_browser__reset_index(struct ui_browser *self); void ui_browser__gotorc(struct ui_browser *self, int y, int x); +void ui_browser__add_exit_key(struct ui_browser *self, int key); +void ui_browser__add_exit_keys(struct ui_browser *self, int keys[]); void __ui_browser__show_title(struct ui_browser *browser, const char *title); void ui_browser__show_title(struct ui_browser *browser, const char *title); int ui_browser__show(struct ui_browser *self, const char *title, const char *helpline, ...); void ui_browser__hide(struct ui_browser *self); int ui_browser__refresh(struct ui_browser *self); -int ui_browser__run(struct ui_browser *browser, int delay_secs); -void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries); +int ui_browser__run(struct ui_browser *self); void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); diff --git a/trunk/tools/perf/util/ui/browsers/annotate.c b/trunk/tools/perf/util/ui/browsers/annotate.c index eb2712ecb601..674b55e686fd 100644 --- a/trunk/tools/perf/util/ui/browsers/annotate.c +++ b/trunk/tools/perf/util/ui/browsers/annotate.c @@ -21,16 +21,12 @@ struct annotate_browser { struct rb_root entries; struct rb_node *curr_hot; struct objdump_line *selection; - int nr_asm_entries; - int nr_entries; - bool hide_src_code; }; struct objdump_line_rb_node { struct rb_node rb_node; double percent; u32 idx; - int idx_asm; }; static inline @@ -39,22 +35,10 @@ struct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self) return (struct objdump_line_rb_node *)(self + 1); } -static bool objdump_line__filter(struct ui_browser *browser, void *entry) -{ - struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); - - if (ab->hide_src_code) { - struct objdump_line *ol = list_entry(entry, struct objdump_line, node); - return ol->offset == -1; - } - - return false; -} - static void annotate_browser__write(struct ui_browser *self, void *entry, int row) { struct annotate_browser *ab = container_of(self, struct annotate_browser, b); - struct objdump_line *ol = list_entry(entry, struct objdump_line, node); + struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); bool current_entry = ui_browser__is_current_entry(self, row); int width = self->width; @@ -184,45 +168,6 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, browser->curr_hot = rb_last(&browser->entries); } -static bool annotate_browser__toggle_source(struct annotate_browser *browser) -{ - struct objdump_line *ol; - struct objdump_line_rb_node *olrb; - off_t offset = browser->b.index - browser->b.top_idx; - - browser->b.seek(&browser->b, offset, SEEK_CUR); - ol = list_entry(browser->b.top, struct objdump_line, node); - olrb = objdump_line__rb(ol); - - if (browser->hide_src_code) { - if (olrb->idx_asm < offset) - offset = olrb->idx; - - browser->b.nr_entries = browser->nr_entries; - browser->hide_src_code = false; - browser->b.seek(&browser->b, -offset, SEEK_CUR); - browser->b.top_idx = olrb->idx - offset; - browser->b.index = olrb->idx; - } else { - if (olrb->idx_asm < 0) { - ui_helpline__puts("Only available for assembly lines."); - browser->b.seek(&browser->b, -offset, SEEK_CUR); - return false; - } - - if (olrb->idx_asm < offset) - offset = olrb->idx_asm; - - browser->b.nr_entries = browser->nr_asm_entries; - browser->hide_src_code = true; - browser->b.seek(&browser->b, -offset, SEEK_CUR); - browser->b.top_idx = olrb->idx_asm - offset; - browser->b.index = olrb->idx_asm; - } - - return true; -} - static int annotate_browser__run(struct annotate_browser *self, int evidx, int nr_events, void(*timer)(void *arg), void *arg, int delay_secs) @@ -230,14 +175,20 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, struct rb_node *nd = NULL; struct map_symbol *ms = self->b.priv; struct symbol *sym = ms->sym; - const char *help = "<-, ESC: exit, TAB/shift+TAB: cycle hottest lines, " - "H: Hottest, -> Line action, S -> Toggle source " - "code view"; + /* + * RIGHT To allow builtin-annotate to cycle thru multiple symbols by + * examining the exit key for this function. + */ + int exit_keys[] = { 'H', NEWT_KEY_TAB, NEWT_KEY_UNTAB, + NEWT_KEY_RIGHT, NEWT_KEY_ENTER, 0 }; int key; - if (ui_browser__show(&self->b, sym->name, help) < 0) + if (ui_browser__show(&self->b, sym->name, + "<- or ESC: exit, TAB/shift+TAB: " + "cycle hottest lines, H: Hottest, -> Line action") < 0) return -1; + ui_browser__add_exit_keys(&self->b, exit_keys); annotate_browser__calc_percent(self, evidx); if (self->curr_hot) @@ -245,8 +196,11 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, nd = self->curr_hot; + if (delay_secs != 0) + newtFormSetTimer(self->b.form, delay_secs * 1000); + while (1) { - key = ui_browser__run(&self->b, delay_secs); + key = ui_browser__run(&self->b); if (delay_secs != 0) { annotate_browser__calc_percent(self, evidx); @@ -290,10 +244,6 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, case 'H': nd = self->curr_hot; break; - case 'S': - if (annotate_browser__toggle_source(self)) - ui_helpline__puts(help); - continue; case NEWT_KEY_ENTER: case NEWT_KEY_RIGHT: if (self->selection == NULL) { @@ -345,13 +295,8 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, timer, arg, delay_secs); } break; - case NEWT_KEY_LEFT: - case NEWT_KEY_ESCAPE: - case 'q': - case CTRL('c'): - goto out; default: - continue; + goto out; } if (nd != NULL) @@ -384,7 +329,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, .refresh = ui_browser__list_head_refresh, .seek = ui_browser__list_head_seek, .write = annotate_browser__write, - .filter = objdump_line__filter, .priv = &ms, }, }; @@ -412,14 +356,9 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, if (browser.b.width < line_len) browser.b.width = line_len; rbpos = objdump_line__rb(pos); - rbpos->idx = browser.nr_entries++; - if (pos->offset != -1) - rbpos->idx_asm = browser.nr_asm_entries++; - else - rbpos->idx_asm = -1; + rbpos->idx = browser.b.nr_entries++; } - browser.b.nr_entries = browser.nr_entries; browser.b.entries = ¬es->src->source, browser.b.width += 18; /* Percentage */ ret = annotate_browser__run(&browser, evidx, nr_events, diff --git a/trunk/tools/perf/util/ui/browsers/hists.c b/trunk/tools/perf/util/ui/browsers/hists.c index b144b108029a..e64d9527f14e 100644 --- a/trunk/tools/perf/util/ui/browsers/hists.c +++ b/trunk/tools/perf/util/ui/browsers/hists.c @@ -301,7 +301,11 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name, void(*timer)(void *arg), void *arg, int delay_secs) { int key; + int delay_msecs = delay_secs * 1000; char title[160]; + int sym_exit_keys[] = { 'a', 'h', 'C', 'd', 'E', 't', 0, }; + int exit_keys[] = { '?', 'h', 'D', NEWT_KEY_LEFT, NEWT_KEY_RIGHT, + NEWT_KEY_TAB, NEWT_KEY_UNTAB, NEWT_KEY_ENTER, 0, }; self->b.entries = &self->hists->entries; self->b.nr_entries = self->hists->nr_entries; @@ -314,14 +318,27 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name, "Press '?' for help on key bindings") < 0) return -1; + if (timer != NULL) + newtFormSetTimer(self->b.form, delay_msecs); + + ui_browser__add_exit_keys(&self->b, exit_keys); + if (self->has_symbols) + ui_browser__add_exit_keys(&self->b, sym_exit_keys); + while (1) { - key = ui_browser__run(&self->b, delay_secs); + key = ui_browser__run(&self->b); switch (key) { case -1: /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */ timer(arg); - ui_browser__update_nr_entries(&self->b, self->hists->nr_entries); + /* + * The timer may have changed the number of entries. + * XXX: Find better way to keep this in synch, probably + * removing this timer function altogether and just sync + * using the hists->lock... + */ + self->b.nr_entries = self->hists->nr_entries; hists__browser_title(self->hists, title, sizeof(title), ev_name, self->dso_filter, self->thread_filter); @@ -600,23 +617,14 @@ static int hist_browser__show_entry(struct hist_browser *self, return printed; } -static void ui_browser__hists_init_top(struct ui_browser *browser) -{ - if (browser->top == NULL) { - struct hist_browser *hb; - - hb = container_of(browser, struct hist_browser, b); - browser->top = rb_first(&hb->hists->entries); - } -} - static unsigned int hist_browser__refresh(struct ui_browser *self) { unsigned row = 0; struct rb_node *nd; struct hist_browser *hb = container_of(self, struct hist_browser, b); - ui_browser__hists_init_top(self); + if (self->top == NULL) + self->top = rb_first(&hb->hists->entries); for (nd = self->top; nd; nd = rb_next(nd)) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); @@ -668,8 +676,6 @@ static void ui_browser__hists_seek(struct ui_browser *self, if (self->nr_entries == 0) return; - ui_browser__hists_init_top(self); - switch (whence) { case SEEK_SET: nd = hists__filter_entries(rb_first(self->entries)); @@ -925,11 +931,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, !ui__dialog_yesno("Do you really want to exit?")) continue; /* Fall thru */ - case 'q': - case CTRL('c'): - goto out_free_stack; default: - continue; + goto out_free_stack; } if (!browser->has_symbols) @@ -979,14 +982,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, he = hist_browser__selected_entry(browser); if (he == NULL) continue; - /* - * Don't let this be freed, say, by hists__decay_entry. - */ - he->used = true; + hist_entry__tui_annotate(he, evsel->idx, nr_events, timer, arg, delay_secs); - he->used = false; - ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); } else if (choice == browse_map) map__browse(browser->selection->map); else if (choice == zoom_dso) { @@ -1063,6 +1061,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, int nr_events, const char *help, void(*timer)(void *arg), void *arg, int delay_secs) { + int exit_keys[] = { NEWT_KEY_ENTER, NEWT_KEY_RIGHT, 0, }; + int delay_msecs = delay_secs * 1000; struct perf_evlist *evlist = menu->b.priv; struct perf_evsel *pos; const char *ev_name, *title = "Available samples"; @@ -1072,8 +1072,13 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, "ESC: exit, ENTER|->: Browse histograms") < 0) return -1; + if (timer != NULL) + newtFormSetTimer(menu->b.form, delay_msecs); + + ui_browser__add_exit_keys(&menu->b, exit_keys); + while (1) { - key = ui_browser__run(&menu->b, delay_secs); + key = ui_browser__run(&menu->b); switch (key) { case -1: @@ -1085,53 +1090,44 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, if (!menu->selection) continue; pos = menu->selection; -browse_hists: perf_evlist__set_selected(evlist, pos); - /* - * Give the calling tool a chance to populate the non - * default evsel resorted hists tree. - */ - if (timer) - timer(arg); +browse_hists: ev_name = event_name(pos); key = perf_evsel__hists_browse(pos, nr_events, help, ev_name, true, timer, arg, delay_secs); ui_browser__show_title(&menu->b, title); - switch (key) { - case NEWT_KEY_TAB: - if (pos->node.next == &evlist->entries) - pos = list_entry(evlist->entries.next, struct perf_evsel, node); - else - pos = list_entry(pos->node.next, struct perf_evsel, node); - goto browse_hists; - case NEWT_KEY_UNTAB: - if (pos->node.prev == &evlist->entries) - pos = list_entry(evlist->entries.prev, struct perf_evsel, node); - else - pos = list_entry(pos->node.prev, struct perf_evsel, node); - goto browse_hists; - case NEWT_KEY_ESCAPE: - if (!ui__dialog_yesno("Do you really want to exit?")) - continue; - /* Fall thru */ - case 'q': - case CTRL('c'): - goto out; - default: - continue; - } + break; case NEWT_KEY_LEFT: continue; case NEWT_KEY_ESCAPE: if (!ui__dialog_yesno("Do you really want to exit?")) continue; /* Fall thru */ + default: + goto out; + } + + switch (key) { + case NEWT_KEY_TAB: + if (pos->node.next == &evlist->entries) + pos = list_entry(evlist->entries.next, struct perf_evsel, node); + else + pos = list_entry(pos->node.next, struct perf_evsel, node); + perf_evlist__set_selected(evlist, pos); + goto browse_hists; + case NEWT_KEY_UNTAB: + if (pos->node.prev == &evlist->entries) + pos = list_entry(evlist->entries.prev, struct perf_evsel, node); + else + pos = list_entry(pos->node.prev, struct perf_evsel, node); + perf_evlist__set_selected(evlist, pos); + goto browse_hists; case 'q': case CTRL('c'): goto out; default: - continue; + break; } } diff --git a/trunk/tools/perf/util/ui/browsers/map.c b/trunk/tools/perf/util/ui/browsers/map.c index 6905bcc8be2d..8462bffe20bc 100644 --- a/trunk/tools/perf/util/ui/browsers/map.c +++ b/trunk/tools/perf/util/ui/browsers/map.c @@ -1,6 +1,5 @@ #include "../libslang.h" #include -#include #include #include #include @@ -109,8 +108,11 @@ static int map_browser__run(struct map_browser *self) verbose ? "" : "restart with -v to use") < 0) return -1; + if (verbose) + ui_browser__add_exit_key(&self->b, '/'); + while (1) { - key = ui_browser__run(&self->b, 0); + key = ui_browser__run(&self->b); if (verbose && key == '/') map_browser__search(self); diff --git a/trunk/tools/perf/util/ui/helpline.h b/trunk/tools/perf/util/ui/helpline.h index 809975759080..ab6028d0c401 100644 --- a/trunk/tools/perf/util/ui/helpline.h +++ b/trunk/tools/perf/util/ui/helpline.h @@ -1,8 +1,6 @@ #ifndef _PERF_UI_HELPLINE_H_ #define _PERF_UI_HELPLINE_H_ 1 -#include - void ui_helpline__init(void); void ui_helpline__pop(void); void ui_helpline__push(const char *msg);