aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/browsers
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2014-08-20 21:15:45 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-08-22 12:12:12 -0400
commitc09a7e755c025558cb882fa20a5f30da738536fa (patch)
tree4d39a5d1ee49bcb397152df63d829fad4c18eb0c /tools/perf/ui/browsers
parentfbe2af45f6bd27ee69fd775303c936c3af4a4807 (diff)
perf hists browser: Cleanup callchain print functions
The hist_browser__show_callchain() and friends don't need to be that complex. They're splitted in 3 pieces - one for traversing top-level tree, other one for special casing first chains in the top-level entries, and last one for recursive traversing inner trees. It led to code duplication and unnecessary complexity IMHO. Simplify the function and consolidate the logic into a single function - it can recursively call itself. A little difference in printing callchains in top-level tree can be handled with a small change. It should have no functional change. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1408583746-5540-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/browsers')
-rw-r--r--tools/perf/ui/browsers/hists.c112
1 files changed, 29 insertions, 83 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d42d8a8f3810..519353d9f5fb 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -502,23 +502,16 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
502 502
503#define LEVEL_OFFSET_STEP 3 503#define LEVEL_OFFSET_STEP 3
504 504
505static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browser, 505static int hist_browser__show_callchain(struct hist_browser *browser,
506 struct callchain_node *chain_node, 506 struct rb_root *root, int level,
507 u64 total, int level, 507 unsigned short row, off_t *row_offset,
508 unsigned short row, 508 u64 total, bool *is_current_entry)
509 off_t *row_offset,
510 bool *is_current_entry)
511{ 509{
512 struct rb_node *node; 510 struct rb_node *node;
513 int first_row = row, offset = level * LEVEL_OFFSET_STEP; 511 int first_row = row, offset = level * LEVEL_OFFSET_STEP;
514 u64 new_total; 512 u64 new_total;
515 513
516 if (callchain_param.mode == CHAIN_GRAPH_REL) 514 node = rb_first(root);
517 new_total = chain_node->children_hit;
518 else
519 new_total = total;
520
521 node = rb_first(&chain_node->rb_root);
522 while (node) { 515 while (node) {
523 struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); 516 struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
524 struct rb_node *next = rb_next(node); 517 struct rb_node *next = rb_next(node);
@@ -535,7 +528,7 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse
535 528
536 if (first) 529 if (first)
537 first = false; 530 first = false;
538 else 531 else if (level > 1)
539 extra_offset = LEVEL_OFFSET_STEP; 532 extra_offset = LEVEL_OFFSET_STEP;
540 533
541 folded_sign = callchain_list__folded(chain); 534 folded_sign = callchain_list__folded(chain);
@@ -547,8 +540,9 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse
547 alloc_str = NULL; 540 alloc_str = NULL;
548 str = callchain_list__sym_name(chain, bf, sizeof(bf), 541 str = callchain_list__sym_name(chain, bf, sizeof(bf),
549 browser->show_dso); 542 browser->show_dso);
550 if (was_first) { 543
551 double percent = cumul * 100.0 / new_total; 544 if (was_first && level > 1) {
545 double percent = cumul * 100.0 / total;
552 546
553 if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) 547 if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
554 str = "Not enough memory!"; 548 str = "Not enough memory!";
@@ -571,78 +565,23 @@ do_next:
571 565
572 if (folded_sign == '-') { 566 if (folded_sign == '-') {
573 const int new_level = level + (extra_offset ? 2 : 1); 567 const int new_level = level + (extra_offset ? 2 : 1);
574 row += hist_browser__show_callchain_node_rb_tree(browser, child, new_total,
575 new_level, row, row_offset,
576 is_current_entry);
577 }
578 if (row == browser->b.rows)
579 goto out;
580 node = next;
581 }
582out:
583 return row - first_row;
584}
585
586static int hist_browser__show_callchain_node(struct hist_browser *browser,
587 struct callchain_node *node,
588 int level, unsigned short row,
589 off_t *row_offset,
590 bool *is_current_entry)
591{
592 struct callchain_list *chain;
593 int first_row = row;
594 int offset = level * LEVEL_OFFSET_STEP;
595 char folded_sign = ' ';
596
597 list_for_each_entry(chain, &node->val, list) {
598 char bf[1024], *s;
599 568
600 folded_sign = callchain_list__folded(chain); 569 if (callchain_param.mode == CHAIN_GRAPH_REL)
570 new_total = child->children_hit;
571 else
572 new_total = total;
601 573
602 if (*row_offset != 0) { 574 row += hist_browser__show_callchain(browser, &child->rb_root,
603 --*row_offset; 575 new_level,
604 continue; 576 row, row_offset,
577 new_total,
578 is_current_entry);
605 } 579 }
606
607 s = callchain_list__sym_name(chain, bf, sizeof(bf),
608 browser->show_dso);
609 hist_browser__show_callchain_entry(browser, chain, row,
610 offset, folded_sign, s,
611 is_current_entry);
612
613 if (++row == browser->b.rows)
614 goto out;
615 }
616
617 if (folded_sign == '-')
618 row += hist_browser__show_callchain_node_rb_tree(browser, node,
619 browser->hists->stats.total_period,
620 level + 1, row,
621 row_offset,
622 is_current_entry);
623out:
624 return row - first_row;
625}
626
627static int hist_browser__show_callchain(struct hist_browser *browser,
628 struct rb_root *chain,
629 int level, unsigned short row,
630 off_t *row_offset,
631 bool *is_current_entry)
632{
633 struct rb_node *nd;
634 int first_row = row;
635
636 for (nd = rb_first(chain); nd; nd = rb_next(nd)) {
637 struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
638
639 row += hist_browser__show_callchain_node(browser, node, level,
640 row, row_offset,
641 is_current_entry);
642 if (row == browser->b.rows) 580 if (row == browser->b.rows)
643 break; 581 break;
582 node = next;
644 } 583 }
645 584out:
646 return row - first_row; 585 return row - first_row;
647} 586}
648 587
@@ -817,9 +756,16 @@ static int hist_browser__show_entry(struct hist_browser *browser,
817 --row_offset; 756 --row_offset;
818 757
819 if (folded_sign == '-' && row != browser->b.rows) { 758 if (folded_sign == '-' && row != browser->b.rows) {
820 printed += hist_browser__show_callchain(browser, &entry->sorted_chain, 759 u64 total = hists__total_period(entry->hists);
760
761 if (symbol_conf.cumulate_callchain)
762 total = entry->stat_acc->period;
763
764 printed += hist_browser__show_callchain(browser,
765 &entry->sorted_chain,
821 1, row, &row_offset, 766 1, row, &row_offset,
822 &current_entry); 767 total, &current_entry);
768
823 if (current_entry) 769 if (current_entry)
824 browser->he_selection = entry; 770 browser->he_selection = entry;
825 } 771 }