aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/newt.c119
-rw-r--r--tools/perf/util/sort.h3
2 files changed, 90 insertions, 32 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;
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 5bf2b744e7b2..dce79d33e339 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -48,7 +48,8 @@ struct hist_entry {
48 struct map_symbol ms; 48 struct map_symbol ms;
49 u64 ip; 49 u64 ip;
50 char level; 50 char level;
51 struct symbol *parent; 51 bool filtered;
52 struct symbol *parent;
52 union { 53 union {
53 unsigned long position; 54 unsigned long position;
54 struct hist_entry *pair; 55 struct hist_entry *pair;