aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-annotate.c
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/builtin-annotate.c
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/builtin-annotate.c')
-rw-r--r--tools/perf/builtin-annotate.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 77bcc9b130f5..08278eda31a5 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -277,7 +277,7 @@ static void hist_entry__print_hits(struct hist_entry *self)
277 printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); 277 printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum);
278} 278}
279 279
280static void annotate_sym(struct hist_entry *he) 280static int hist_entry__tty_annotate(struct hist_entry *he)
281{ 281{
282 struct map *map = he->ms.map; 282 struct map *map = he->ms.map;
283 struct dso *dso = map->dso; 283 struct dso *dso = map->dso;
@@ -288,7 +288,7 @@ static void annotate_sym(struct hist_entry *he)
288 struct objdump_line *pos, *n; 288 struct objdump_line *pos, *n;
289 289
290 if (hist_entry__annotate(he, &head) < 0) 290 if (hist_entry__annotate(he, &head) < 0)
291 return; 291 return -1;
292 292
293 if (full_paths) 293 if (full_paths)
294 d_filename = filename; 294 d_filename = filename;
@@ -317,30 +317,59 @@ static void annotate_sym(struct hist_entry *he)
317 317
318 if (print_line) 318 if (print_line)
319 free_source_line(he, len); 319 free_source_line(he, len);
320
321 return 0;
320} 322}
321 323
322static void hists__find_annotations(struct hists *self) 324static void hists__find_annotations(struct hists *self)
323{ 325{
324 struct rb_node *nd; 326 struct rb_node *first = rb_first(&self->entries), *nd = first;
327 int key = KEY_RIGHT;
325 328
326 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 329 while (nd) {
327 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); 330 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
328 struct sym_priv *priv; 331 struct sym_priv *priv;
329 332
330 if (he->ms.sym == NULL) 333 if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned)
331 continue; 334 goto find_next;
332 335
333 priv = symbol__priv(he->ms.sym); 336 priv = symbol__priv(he->ms.sym);
334 if (priv->hist == NULL) 337 if (priv->hist == NULL) {
338find_next:
339 if (key == KEY_LEFT)
340 nd = rb_prev(nd);
341 else
342 nd = rb_next(nd);
335 continue; 343 continue;
344 }
336 345
337 annotate_sym(he); 346 if (use_browser) {
338 /* 347 key = hist_entry__tui_annotate(he);
339 * Since we have a hist_entry per IP for the same symbol, free 348 if (is_exit_key(key))
340 * he->ms.sym->hist to signal we already processed this symbol. 349 break;
341 */ 350 switch (key) {
342 free(priv->hist); 351 case KEY_RIGHT:
343 priv->hist = NULL; 352 case '\t':
353 nd = rb_next(nd);
354 break;
355 case KEY_LEFT:
356 if (nd == first)
357 continue;
358 nd = rb_prev(nd);
359 default:
360 break;
361 }
362 } else {
363 hist_entry__tty_annotate(he);
364 nd = rb_next(nd);
365 /*
366 * Since we have a hist_entry per IP for the same
367 * symbol, free he->ms.sym->hist to signal we already
368 * processed this symbol.
369 */
370 free(priv->hist);
371 priv->hist = NULL;
372 }
344 } 373 }
345} 374}
346 375
@@ -416,6 +445,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
416{ 445{
417 argc = parse_options(argc, argv, options, annotate_usage, 0); 446 argc = parse_options(argc, argv, options, annotate_usage, 0);
418 447
448 setup_browser();
449
419 symbol_conf.priv_size = sizeof(struct sym_priv); 450 symbol_conf.priv_size = sizeof(struct sym_priv);
420 symbol_conf.try_vmlinux_path = true; 451 symbol_conf.try_vmlinux_path = true;
421 452
@@ -435,8 +466,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
435 sym_hist_filter = argv[0]; 466 sym_hist_filter = argv[0];
436 } 467 }
437 468
438 setup_pager();
439
440 if (field_sep && *field_sep == '.') { 469 if (field_sep && *field_sep == '.') {
441 pr_err("'.' is the only non valid --field-separator argument\n"); 470 pr_err("'.' is the only non valid --field-separator argument\n");
442 return -1; 471 return -1;