[PATCH 5/5] perf hists browser: Consolidate callchain print functions in TUI
From: Namhyung Kim
Date: Wed Aug 20 2014 - 04:10:47 EST
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 <fweisbec@xxxxxxxxx>
Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
---
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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/