aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-08-10 14:14:53 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-08-10 14:14:53 -0400
commitf1e9214cc99644101d957c5c660946c6f2f86d7c (patch)
tree50fa9e5b07134cfc53e09aa2d8d79695a34766d9 /tools
parent9e22d6377ce6f31b1cc0bff16daeda2780495061 (diff)
perf annotate: Cycle thru sorted lines with samples
The annotate TUI now starts centered on the line with most samples, i.e. the hottest line in the annotated function. Pressing TAB will center on the second hottest function and so on. Shift+TAB goes in the other direction. This way one can more easily sift thru the function hotspots. Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/ui/browsers/annotate.c102
1 files changed, 77 insertions, 25 deletions
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c
index d2156aebd4f1..73e78ef38a50 100644
--- a/tools/perf/util/ui/browsers/annotate.c
+++ b/tools/perf/util/ui/browsers/annotate.c
@@ -17,6 +17,7 @@ static void ui__error_window(const char *fmt, ...)
17struct annotate_browser { 17struct annotate_browser {
18 struct ui_browser b; 18 struct ui_browser b;
19 struct rb_root entries; 19 struct rb_root entries;
20 struct rb_node *curr_hot;
20}; 21};
21 22
22struct objdump_line_rb_node { 23struct objdump_line_rb_node {
@@ -110,12 +111,83 @@ static void objdump__insert_line(struct rb_root *self,
110 rb_insert_color(&line->rb_node, self); 111 rb_insert_color(&line->rb_node, self);
111} 112}
112 113
114static void annotate_browser__set_top(struct annotate_browser *self,
115 struct rb_node *nd)
116{
117 struct objdump_line_rb_node *rbpos;
118 struct objdump_line *pos;
119 unsigned back;
120
121 ui_browser__refresh_dimensions(&self->b);
122 back = self->b.height / 2;
123 rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node);
124 pos = ((struct objdump_line *)rbpos) - 1;
125 self->b.top_idx = self->b.index = rbpos->idx;
126
127 while (self->b.top_idx != 0 && back != 0) {
128 pos = list_entry(pos->node.prev, struct objdump_line, node);
129
130 --self->b.top_idx;
131 --back;
132 }
133
134 self->b.top = pos;
135 self->curr_hot = nd;
136}
137
138static int annotate_browser__run(struct annotate_browser *self,
139 struct newtExitStruct *es)
140{
141 struct rb_node *nd;
142 struct hist_entry *he = self->b.priv;
143
144 if (ui_browser__show(&self->b, he->ms.sym->name) < 0)
145 return -1;
146
147 ui_helpline__fpush("<- or ESC: exit, TAB/shift+TAB: cycle thru samples");
148 newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT);
149
150 nd = self->curr_hot;
151 if (nd) {
152 newtFormAddHotKey(self->b.form, NEWT_KEY_TAB);
153 newtFormAddHotKey(self->b.form, NEWT_KEY_UNTAB);
154 }
155
156 while (1) {
157 ui_browser__run(&self->b, es);
158
159 if (es->reason != NEWT_EXIT_HOTKEY)
160 break;
161
162 switch (es->u.key) {
163 case NEWT_KEY_TAB:
164 nd = rb_prev(nd);
165 if (nd == NULL)
166 nd = rb_last(&self->entries);
167 annotate_browser__set_top(self, nd);
168 break;
169 case NEWT_KEY_UNTAB:
170 nd = rb_next(nd);
171 if (nd == NULL)
172 nd = rb_first(&self->entries);
173 annotate_browser__set_top(self, nd);
174 break;
175 default:
176 goto out;
177 }
178 }
179out:
180 newtFormDestroy(self->b.form);
181 newtPopWindow();
182 ui_helpline__pop();
183 return 0;
184}
185
113int hist_entry__tui_annotate(struct hist_entry *self) 186int hist_entry__tui_annotate(struct hist_entry *self)
114{ 187{
115 struct newtExitStruct es; 188 struct newtExitStruct es;
116 struct objdump_line *pos, *n; 189 struct objdump_line *pos, *n;
117 struct objdump_line_rb_node *rbpos; 190 struct objdump_line_rb_node *rbpos;
118 struct rb_node *nd;
119 LIST_HEAD(head); 191 LIST_HEAD(head);
120 struct annotate_browser browser = { 192 struct annotate_browser browser = {
121 .b = { 193 .b = {
@@ -156,35 +228,15 @@ int hist_entry__tui_annotate(struct hist_entry *self)
156 /* 228 /*
157 * Position the browser at the hottest line. 229 * Position the browser at the hottest line.
158 */ 230 */
159 nd = rb_last(&browser.entries); 231 browser.curr_hot = rb_last(&browser.entries);
160 if (nd != NULL) { 232 if (browser.curr_hot)
161 unsigned back; 233 annotate_browser__set_top(&browser, browser.curr_hot);
162
163 ui_browser__refresh_dimensions(&browser.b);
164 back = browser.b.height / 2;
165 rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node);
166 pos = ((struct objdump_line *)rbpos) - 1;
167 browser.b.top_idx = browser.b.index = rbpos->idx;
168
169 while (browser.b.top_idx != 0 && back != 0) {
170 pos = list_entry(pos->node.prev, struct objdump_line, node);
171
172 --browser.b.top_idx;
173 --back;
174 }
175
176 browser.b.top = pos;
177 }
178 234
179 browser.b.width += 18; /* Percentage */ 235 browser.b.width += 18; /* Percentage */
180 ui_browser__show(&browser.b, self->ms.sym->name); 236 ret = annotate_browser__run(&browser, &es);
181 ret = ui_browser__run(&browser.b, &es);
182 newtFormDestroy(browser.b.form);
183 newtPopWindow();
184 list_for_each_entry_safe(pos, n, &head, node) { 237 list_for_each_entry_safe(pos, n, &head, node) {
185 list_del(&pos->node); 238 list_del(&pos->node);
186 objdump_line__free(pos); 239 objdump_line__free(pos);
187 } 240 }
188 ui_helpline__pop();
189 return ret; 241 return ret;
190} 242}