From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751733AbaHTIJE (ORCPT ); Wed, 20 Aug 2014 04:09:04 -0400 Received: from lgeamrelo04.lge.com ([156.147.1.127]:60638 "EHLO lgeamrelo04.lge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751344AbaHTIIE (ORCPT ); Wed, 20 Aug 2014 04:08:04 -0400 X-Original-SENDERIP: 10.177.220.181 X-Original-MAILFROM: namhyung@kernel.org From: Namhyung Kim To: Arnaldo Carvalho de Melo Cc: Peter Zijlstra , Ingo Molnar , Paul Mackerras , Namhyung Kim , Namhyung Kim , LKML , Jiri Olsa , David Ahern , Andi Kleen , Frederic Weisbecker Subject: [PATCH 5/5] perf hists browser: Consolidate callchain print functions in TUI Date: Wed, 20 Aug 2014 17:08:00 +0900 Message-Id: <1408522080-26556-6-git-send-email-namhyung@kernel.org> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1408522080-26556-1-git-send-email-namhyung@kernel.org> References: <1408522080-26556-1-git-send-email-namhyung@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently there're two callchain print functions in TUI - one for the hists browser and another for file dump. They do almost same job so it'd be better consolidate the codes. Cc: Frederic Weisbecker Signed-off-by: Namhyung Kim --- tools/perf/ui/browsers/hists.c | 211 +++++++++++++++-------------------------- 1 file changed, 77 insertions(+), 134 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 05ff679777a1..8ad20e13044f 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -477,20 +477,32 @@ static char *callchain_list__sym_name(struct callchain_list *cl, return bf; } +struct callchain_print_arg { + /* for hists browser */ + unsigned short row; + off_t row_offset; + bool is_current_entry; + + /* for file dump */ + FILE *fp; + int printed; +}; + static void hist_browser__show_callchain_entry(struct hist_browser *browser, struct callchain_list *chain, - unsigned short row, int offset, - char folded_sign, const char *str, - bool *is_current_entry) + const char *str, int offset, + struct callchain_print_arg *arg) { int color, width; + unsigned short row = arg->row; + char folded_sign = callchain_list__folded(chain); color = HE_COLORSET_NORMAL; width = browser->b.width - (offset + 2); if (ui_browser__is_current_entry(&browser->b, row)) { browser->selection = &chain->ms; color = HE_COLORSET_SELECTED; - *is_current_entry = true; + arg->is_current_entry = true; } ui_browser__set_color(&browser->b, color); @@ -498,17 +510,40 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser, slsmg_write_nstring(" ", offset); slsmg_printf("%c ", folded_sign); slsmg_write_nstring(str, width); + + /* + * increase row here so that we can reuse the + * hist_browser__show_callchain() for dumping the whole + * callchain to a file. + */ + arg->row++; +} + +static void hist_browser__fprintf_callchain_entry(struct hist_browser *b __maybe_unused, + struct callchain_list *chain, + const char *str, int offset, + struct callchain_print_arg *arg) +{ + char folded_sign = callchain_list__folded(chain); + + arg->printed += fprintf(arg->fp, "%*s%c %s\n", offset, " ", + folded_sign, str); } +typedef void (*print_callchain_entry_fn)(struct hist_browser *browser, + struct callchain_list *chain, + const char *str, int offset, + struct callchain_print_arg *arg); + #define LEVEL_OFFSET_STEP 3 static int hist_browser__show_callchain(struct hist_browser *browser, - struct rb_root *root, int level, - unsigned short row, off_t *row_offset, - u64 total, bool *is_current_entry) + struct rb_root *root, int level, u64 total, + print_callchain_entry_fn print, + struct callchain_print_arg *arg) { struct rb_node *node; - int first_row = row; + int first_row = arg->row; int offset = level * LEVEL_OFFSET_STEP; bool has_single_node = (rb_first(root) == rb_last(root)); u64 new_total; @@ -532,8 +567,8 @@ static int hist_browser__show_callchain(struct hist_browser *browser, extra_offset = LEVEL_OFFSET_STEP; folded_sign = callchain_list__folded(chain); - if (*row_offset != 0) { - --*row_offset; + if (arg->row_offset != 0) { + arg->row_offset--; goto do_next; } @@ -550,13 +585,11 @@ static int hist_browser__show_callchain(struct hist_browser *browser, str = alloc_str; } - hist_browser__show_callchain_entry(browser, chain, row, - offset + extra_offset, - folded_sign, str, - is_current_entry); + print(browser, chain, str, offset + extra_offset, arg); + free(alloc_str); - if (++row == browser->b.rows) + if (arg->row == browser->b.rows) goto out; do_next: if (folded_sign == '+') @@ -571,16 +604,15 @@ do_next: else new_total = total; - row += hist_browser__show_callchain(browser, &child->rb_root, - level + 1 + !!extra_offset, - row, row_offset, - new_total, - is_current_entry); - if (row == browser->b.rows) + hist_browser__show_callchain(browser, &child->rb_root, + level + 1 + !!extra_offset, + new_total, print, arg); + + if (arg->row == browser->b.rows) break; } out: - return row - first_row; + return arg->row - first_row; } struct hpp_arg { @@ -755,16 +787,21 @@ static int hist_browser__show_entry(struct hist_browser *browser, if (folded_sign == '-' && row != browser->b.rows) { u64 total = hists__total_period(entry->hists); + struct callchain_print_arg arg = { + .row = row, + .row_offset = row_offset, + .is_current_entry = current_entry, + }; if (symbol_conf.cumulate_callchain) total = entry->stat_acc->period; printed += hist_browser__show_callchain(browser, - &entry->sorted_chain, - 1, row, &row_offset, - total, ¤t_entry); + &entry->sorted_chain, 1, total, + hist_browser__show_callchain_entry, + &arg); - if (current_entry) + if (arg.is_current_entry) browser->he_selection = entry; } @@ -1020,112 +1057,6 @@ do_offset: } } -static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *browser, - struct callchain_node *chain_node, - u64 total, int level, - FILE *fp) -{ - struct rb_node *node; - int offset = level * LEVEL_OFFSET_STEP; - u64 new_total; - int printed = 0; - - if (callchain_param.mode == CHAIN_GRAPH_REL) - new_total = chain_node->children_hit; - else - new_total = total; - - node = rb_first(&chain_node->rb_root); - while (node) { - struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); - struct rb_node *next = rb_next(node); - u64 cumul = callchain_cumul_hits(child); - struct callchain_list *chain; - char folded_sign = ' '; - int first = true; - int extra_offset = 0; - - list_for_each_entry(chain, &child->val, list) { - char bf[1024], *alloc_str; - const char *str; - bool was_first = first; - - if (first) - first = false; - else - extra_offset = LEVEL_OFFSET_STEP; - - folded_sign = callchain_list__folded(chain); - - alloc_str = NULL; - str = callchain_list__sym_name(chain, bf, sizeof(bf), - browser->show_dso); - if (was_first) { - double percent = cumul * 100.0 / new_total; - - if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) - str = "Not enough memory!"; - else - str = alloc_str; - } - - printed += fprintf(fp, "%*s%c %s\n", offset + extra_offset, " ", folded_sign, str); - free(alloc_str); - if (folded_sign == '+') - break; - } - - if (folded_sign == '-') { - const int new_level = level + (extra_offset ? 2 : 1); - printed += hist_browser__fprintf_callchain_node_rb_tree(browser, child, new_total, - new_level, fp); - } - - node = next; - } - - return printed; -} - -static int hist_browser__fprintf_callchain_node(struct hist_browser *browser, - struct callchain_node *node, - int level, FILE *fp) -{ - struct callchain_list *chain; - int offset = level * LEVEL_OFFSET_STEP; - char folded_sign = ' '; - int printed = 0; - - list_for_each_entry(chain, &node->val, list) { - char bf[1024], *s; - - folded_sign = callchain_list__folded(chain); - s = callchain_list__sym_name(chain, bf, sizeof(bf), browser->show_dso); - printed += fprintf(fp, "%*s%c %s\n", offset, " ", folded_sign, s); - } - - if (folded_sign == '-') - printed += hist_browser__fprintf_callchain_node_rb_tree(browser, node, - browser->hists->stats.total_period, - level + 1, fp); - return printed; -} - -static int hist_browser__fprintf_callchain(struct hist_browser *browser, - struct rb_root *chain, int level, FILE *fp) -{ - struct rb_node *nd; - int printed = 0; - - for (nd = rb_first(chain); nd; nd = rb_next(nd)) { - struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); - - printed += hist_browser__fprintf_callchain_node(browser, node, level, fp); - } - - return printed; -} - static int hist_browser__fprintf_entry(struct hist_browser *browser, struct hist_entry *he, FILE *fp) { @@ -1161,8 +1092,20 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, } printed += fprintf(fp, "%s\n", rtrim(s)); - if (folded_sign == '-') - printed += hist_browser__fprintf_callchain(browser, &he->sorted_chain, 1, fp); + if (folded_sign == '-') { + u64 total = hists__total_period(he->hists); + struct callchain_print_arg arg = { + .fp = fp, + }; + + if (symbol_conf.cumulate_callchain) + total = he->stat_acc->period; + + hist_browser__show_callchain(browser, &he->sorted_chain, 1, total, + hist_browser__fprintf_callchain_entry, + &arg); + printed += arg.printed; + } return printed; } -- 2.0.0