diff options
author | Namhyung Kim <namhyung@kernel.org> | 2014-08-20 21:15:45 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-08-22 12:12:12 -0400 |
commit | c09a7e755c025558cb882fa20a5f30da738536fa (patch) | |
tree | 4d39a5d1ee49bcb397152df63d829fad4c18eb0c /tools/perf/ui/browsers | |
parent | fbe2af45f6bd27ee69fd775303c936c3af4a4807 (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.c | 112 |
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 | ||
505 | static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browser, | 505 | static 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 | } | ||
582 | out: | ||
583 | return row - first_row; | ||
584 | } | ||
585 | |||
586 | static 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); | ||
623 | out: | ||
624 | return row - first_row; | ||
625 | } | ||
626 | |||
627 | static 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 | 584 | out: | |
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 | ¤t_entry); | 767 | total, ¤t_entry); |
768 | |||
823 | if (current_entry) | 769 | if (current_entry) |
824 | browser->he_selection = entry; | 770 | browser->he_selection = entry; |
825 | } | 771 | } |