aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/newt.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-04-03 21:44:37 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-04-03 21:45:00 -0400
commita5e29aca02fcecd086ac160ea29244cae6b4305e (patch)
tree9cf2775c72381afe8ea23a9a6da179f76436c1ea /tools/perf/util/newt.c
parent83753190c136901c916df267703937e60f24b8b8 (diff)
perf TUI: Add a "Zoom into COMM(PID) thread" and reverse operations
Now one can press the right arrow key and in addition to being able to filter by DSO, filter out by thread too, or a combination of both filters. With this one can start collecting events for the whole system, then focus on a subset of the collected data quickly. Cc: Avi Kivity <avi@redhat.com> 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.c82
1 files changed, 74 insertions, 8 deletions
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index bbf725d4b38d..6d6e022d7708 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -490,6 +490,11 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
490 return 0; 490 return 0;
491} 491}
492 492
493enum hist_filter {
494 HIST_FILTER__DSO,
495 HIST_FILTER__THREAD,
496};
497
493static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso, 498static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso,
494 u64 *session_total) 499 u64 *session_total)
495{ 500{
@@ -502,10 +507,10 @@ static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso,
502 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 507 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
503 508
504 if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) { 509 if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) {
505 h->filtered = true; 510 h->filtered |= (1 << HIST_FILTER__DSO);
506 continue; 511 continue;
507 } 512 }
508 h->filtered = false; 513 h->filtered &= ~(1 << HIST_FILTER__DSO);
509 ++nr_hists; 514 ++nr_hists;
510 *session_total += h->count; 515 *session_total += h->count;
511 } 516 }
@@ -513,12 +518,54 @@ static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso,
513 return nr_hists; 518 return nr_hists;
514} 519}
515 520
521static u64 hists__filter_by_thread(struct rb_root *hists, const struct thread *thread,
522 u64 *session_total)
523{
524 struct rb_node *nd;
525 u64 nr_hists = 0;
526
527 *session_total = 0;
528
529 for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
530 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
531
532 if (thread != NULL && h->thread != thread) {
533 h->filtered |= (1 << HIST_FILTER__THREAD);
534 continue;
535 }
536 h->filtered &= ~(1 << HIST_FILTER__THREAD);
537 ++nr_hists;
538 *session_total += h->count;
539 }
540
541 return nr_hists;
542}
543
544static struct thread *hist_browser__selected_thread(struct hist_browser *self)
545{
546 int *indexes;
547
548 if (!symbol_conf.use_callchain)
549 goto out;
550
551 indexes = newtCheckboxTreeFindItem(self->tree, (void *)self->selection);
552 if (indexes) {
553 bool is_hist_entry = indexes[1] == NEWT_ARG_LAST;
554 free(indexes);
555 if (is_hist_entry)
556 goto out;
557 }
558 return NULL;
559out:
560 return *(struct thread **)(self->selection + 1);
561}
562
516int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, 563int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
517 u64 session_total, const char *helpline, 564 u64 session_total, const char *helpline,
518 const char *input_name) 565 const char *input_name)
519{ 566{
520 struct newtExitStruct es; 567 struct newtExitStruct es;
521 bool dso_filtered = false; 568 bool dso_filtered = false, thread_filtered = false;
522 int err = -1; 569 int err = -1;
523 struct hist_browser *browser = hist_browser__new(); 570 struct hist_browser *browser = hist_browser__new();
524 571
@@ -531,9 +578,10 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
531 goto out; 578 goto out;
532 579
533 while (1) { 580 while (1) {
581 const struct thread *thread;
534 char *options[16]; 582 char *options[16];
535 int nr_options = 0, choice = 0, i, 583 int nr_options = 0, choice = 0, i,
536 annotate = -2, zoom_dso = -2; 584 annotate = -2, zoom_dso = -2, zoom_thread = -2;
537 585
538 newtFormRun(browser->form, &es); 586 newtFormRun(browser->form, &es);
539 if (es.reason == NEWT_EXIT_HOTKEY) { 587 if (es.reason == NEWT_EXIT_HOTKEY) {
@@ -561,6 +609,13 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
561 browser->selection->map->dso->short_name)) > 0) 609 browser->selection->map->dso->short_name)) > 0)
562 zoom_dso = nr_options++; 610 zoom_dso = nr_options++;
563 611
612 thread = hist_browser__selected_thread(browser);
613 if (thread != NULL &&
614 asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
615 (thread_filtered ? "out of" : "into"),
616 (thread->comm_set ? thread->comm : ""), thread->pid) > 0)
617 zoom_thread = nr_options++;
618
564 options[nr_options++] = (char *)"Exit"; 619 options[nr_options++] = (char *)"Exit";
565 620
566 choice = popup_menu(nr_options, options); 621 choice = popup_menu(nr_options, options);
@@ -570,6 +625,9 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
570 625
571 if (choice == nr_options - 1) 626 if (choice == nr_options - 1)
572 break; 627 break;
628
629 if (choice == -1)
630 continue;
573do_annotate: 631do_annotate:
574 if (choice == annotate) { 632 if (choice == annotate) {
575 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) { 633 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
@@ -581,13 +639,21 @@ do_annotate:
581 } 639 }
582 map_symbol__annotate_browser(browser->selection, 640 map_symbol__annotate_browser(browser->selection,
583 input_name); 641 input_name);
584 } if (choice == zoom_dso) { 642 } else if (choice == zoom_dso) {
585 hists__filter_by_dso(hists, 643 nr_hists = hists__filter_by_dso(hists,
586 dso_filtered ? NULL : browser->selection->map->dso, 644 (dso_filtered ? NULL :
587 &session_total); 645 browser->selection->map->dso),
646 &session_total);
588 dso_filtered = !dso_filtered; 647 dso_filtered = !dso_filtered;
589 if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0) 648 if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
590 goto out; 649 goto out;
650 } else if (choice == zoom_thread) {
651 nr_hists = hists__filter_by_thread(hists,
652 (thread_filtered ? NULL : thread),
653 &session_total);
654 thread_filtered = !thread_filtered;
655 if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
656 goto out;
591 } 657 }
592 } 658 }
593 err = 0; 659 err = 0;