aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/newt.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-04-03 15:30:44 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-04-03 21:36:56 -0400
commit83753190c136901c916df267703937e60f24b8b8 (patch)
treedc0c7fa2056fe2e01c65627ed87c3f30c8b9aa5a /tools/perf/util/newt.c
parent22a4e4c435bbc0edccc2e7e5143ce4fbe9679e2d (diff)
perf newt: Add a "Zoom into foo.so DSO" and reverse operations
Clicking on -> will bring as one of the popup menu options a "Zoom into CURRENT DSO", i.e. CURRENT will be replaced by the name of the DSO in the current line. Choosing this option will filter out all samples that didn't took place in a symbol in this DSO. After that the option reverts to "Zoom out of CURRENT DSO", to allow going back to the more compreensive view, not filtered by DSO. Future similar operations will include zooming into a particular thread, COMM, CPU, "last minute", "last N usecs", etc. Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/newt.c')
-rw-r--r--tools/perf/util/newt.c119
1 files changed, 88 insertions, 31 deletions
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index c93bc2a2d137..bbf725d4b38d 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -94,7 +94,7 @@ static newtComponent newt_form__new(void)
94 return self; 94 return self;
95} 95}
96 96
97static int popup_menu(int argc, const char *argv[]) 97static int popup_menu(int argc, char * const argv[])
98{ 98{
99 struct newtExitStruct es; 99 struct newtExitStruct es;
100 int i, rc = -1, max_len = 5; 100 int i, rc = -1, max_len = 5;
@@ -397,22 +397,8 @@ static struct hist_browser *hist_browser__new(void)
397{ 397{
398 struct hist_browser *self = malloc(sizeof(*self)); 398 struct hist_browser *self = malloc(sizeof(*self));
399 399
400 if (self != NULL) { 400 if (self != NULL)
401 char seq[] = "."; 401 self->form = NULL;
402 int rows;
403
404 newtGetScreenSize(NULL, &rows);
405
406 if (symbol_conf.use_callchain)
407 self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
408 NEWT_FLAG_SCROLL);
409 else
410 self->tree = newtListbox(0, 0, rows - 5,
411 (NEWT_FLAG_SCROLL |
412 NEWT_FLAG_RETURNEXIT));
413 newtComponentAddCallback(self->tree, hist_browser__selection,
414 &self->selection);
415 }
416 402
417 return self; 403 return self;
418} 404}
@@ -431,6 +417,30 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
431 struct ui_progress *progress; 417 struct ui_progress *progress;
432 struct rb_node *nd; 418 struct rb_node *nd;
433 u64 curr_hist = 0; 419 u64 curr_hist = 0;
420 char seq[] = ".";
421 char str[256];
422
423 if (self->form) {
424 newtFormDestroy(self->form);
425 newtPopWindow();
426 }
427
428 snprintf(str, sizeof(str), "Samples: %Ld ",
429 session_total);
430 newtDrawRootText(0, 0, str);
431
432 newtGetScreenSize(NULL, &rows);
433
434 if (symbol_conf.use_callchain)
435 self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
436 NEWT_FLAG_SCROLL);
437 else
438 self->tree = newtListbox(0, 0, rows - 5,
439 (NEWT_FLAG_SCROLL |
440 NEWT_FLAG_RETURNEXIT));
441
442 newtComponentAddCallback(self->tree, hist_browser__selection,
443 &self->selection);
434 444
435 progress = ui_progress__new("Adding entries to the browser...", nr_hists); 445 progress = ui_progress__new("Adding entries to the browser...", nr_hists);
436 if (progress == NULL) 446 if (progress == NULL)
@@ -439,7 +449,12 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
439 idx = 0; 449 idx = 0;
440 for (nd = rb_first(hists); nd; nd = rb_next(nd)) { 450 for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
441 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 451 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
442 int len = hist_entry__append_browser(h, self->tree, session_total); 452 int len;
453
454 if (h->filtered)
455 continue;
456
457 len = hist_entry__append_browser(h, self->tree, session_total);
443 if (len > max_len) 458 if (len > max_len)
444 max_len = len; 459 max_len = len;
445 if (symbol_conf.use_callchain) 460 if (symbol_conf.use_callchain)
@@ -463,6 +478,9 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
463 newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0), 478 newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0),
464 rows - 5, "Report"); 479 rows - 5, "Report");
465 self->form = newt_form__new(); 480 self->form = newt_form__new();
481 if (self->form == NULL)
482 return -1;
483
466 newtFormAddHotKey(self->form, 'A'); 484 newtFormAddHotKey(self->form, 'A');
467 newtFormAddHotKey(self->form, 'a'); 485 newtFormAddHotKey(self->form, 'a');
468 newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); 486 newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
@@ -472,29 +490,50 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
472 return 0; 490 return 0;
473} 491}
474 492
493static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso,
494 u64 *session_total)
495{
496 struct rb_node *nd;
497 u64 nr_hists = 0;
498
499 *session_total = 0;
500
501 for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
502 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
503
504 if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) {
505 h->filtered = true;
506 continue;
507 }
508 h->filtered = false;
509 ++nr_hists;
510 *session_total += h->count;
511 }
512
513 return nr_hists;
514}
515
475int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, 516int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
476 u64 session_total, const char *helpline, 517 u64 session_total, const char *helpline,
477 const char *input_name) 518 const char *input_name)
478{ 519{
479 struct newtExitStruct es; 520 struct newtExitStruct es;
480 char str[1024]; 521 bool dso_filtered = false;
481 int err = -1; 522 int err = -1;
482 struct hist_browser *browser = hist_browser__new(); 523 struct hist_browser *browser = hist_browser__new();
483 524
484 if (browser == NULL) 525 if (browser == NULL)
485 return -1; 526 return -1;
486 527
487 snprintf(str, sizeof(str), "Samples: %Ld", session_total);
488 newtDrawRootText(0, 0, str);
489 newtPushHelpLine(helpline); 528 newtPushHelpLine(helpline);
490 529
491 if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0) 530 if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
492 goto out; 531 goto out;
493 532
494 while (1) { 533 while (1) {
495 char annotate[512]; 534 char *options[16];
496 const char *options[2]; 535 int nr_options = 0, choice = 0, i,
497 int nr_options = 0, choice = 0; 536 annotate = -2, zoom_dso = -2;
498 537
499 newtFormRun(browser->form, &es); 538 newtFormRun(browser->form, &es);
500 if (es.reason == NEWT_EXIT_HOTKEY) { 539 if (es.reason == NEWT_EXIT_HOTKEY) {
@@ -510,18 +549,29 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
510 } 549 }
511 } 550 }
512 551
513 if (browser->selection->sym != NULL) { 552 if (browser->selection->sym != NULL &&
514 snprintf(annotate, sizeof(annotate), 553 asprintf(&options[nr_options], "Annotate %s",
515 "Annotate %s", browser->selection->sym->name); 554 browser->selection->sym->name) > 0)
516 options[nr_options++] = annotate; 555 annotate = nr_options++;
517 } 556
557 if (browser->selection->map != NULL &&
558 asprintf(&options[nr_options], "Zoom %s %s DSO",
559 dso_filtered ? "out of" : "into",
560 (browser->selection->map->dso->kernel ? "the Kernel" :
561 browser->selection->map->dso->short_name)) > 0)
562 zoom_dso = nr_options++;
563
564 options[nr_options++] = (char *)"Exit";
518 565
519 options[nr_options++] = "Exit";
520 choice = popup_menu(nr_options, options); 566 choice = popup_menu(nr_options, options);
567
568 for (i = 0; i < nr_options - 1; ++i)
569 free(options[i]);
570
521 if (choice == nr_options - 1) 571 if (choice == nr_options - 1)
522 break; 572 break;
523do_annotate: 573do_annotate:
524 if (browser->selection->sym != NULL && choice >= 0) { 574 if (choice == annotate) {
525 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) { 575 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
526 newtPopHelpLine(); 576 newtPopHelpLine();
527 newtPushHelpLine("No vmlinux file found, can't " 577 newtPushHelpLine("No vmlinux file found, can't "
@@ -531,6 +581,13 @@ do_annotate:
531 } 581 }
532 map_symbol__annotate_browser(browser->selection, 582 map_symbol__annotate_browser(browser->selection,
533 input_name); 583 input_name);
584 } if (choice == zoom_dso) {
585 hists__filter_by_dso(hists,
586 dso_filtered ? NULL : browser->selection->map->dso,
587 &session_total);
588 dso_filtered = !dso_filtered;
589 if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
590 goto out;
534 } 591 }
535 } 592 }
536 err = 0; 593 err = 0;