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>
This commit is contained in:
parent
fbe2af45f6
commit
c09a7e755c
|
@ -502,23 +502,16 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
|
|||
|
||||
#define LEVEL_OFFSET_STEP 3
|
||||
|
||||
static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browser,
|
||||
struct callchain_node *chain_node,
|
||||
u64 total, int level,
|
||||
unsigned short row,
|
||||
off_t *row_offset,
|
||||
bool *is_current_entry)
|
||||
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_node *node;
|
||||
int first_row = row, offset = level * LEVEL_OFFSET_STEP;
|
||||
u64 new_total;
|
||||
|
||||
if (callchain_param.mode == CHAIN_GRAPH_REL)
|
||||
new_total = chain_node->children_hit;
|
||||
else
|
||||
new_total = total;
|
||||
|
||||
node = rb_first(&chain_node->rb_root);
|
||||
node = rb_first(root);
|
||||
while (node) {
|
||||
struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
|
||||
struct rb_node *next = rb_next(node);
|
||||
|
@ -535,7 +528,7 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse
|
|||
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
else if (level > 1)
|
||||
extra_offset = LEVEL_OFFSET_STEP;
|
||||
|
||||
folded_sign = callchain_list__folded(chain);
|
||||
|
@ -547,8 +540,9 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse
|
|||
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 (was_first && level > 1) {
|
||||
double percent = cumul * 100.0 / total;
|
||||
|
||||
if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
|
||||
str = "Not enough memory!";
|
||||
|
@ -571,81 +565,26 @@ do_next:
|
|||
|
||||
if (folded_sign == '-') {
|
||||
const int new_level = level + (extra_offset ? 2 : 1);
|
||||
row += hist_browser__show_callchain_node_rb_tree(browser, child, new_total,
|
||||
new_level, row, row_offset,
|
||||
is_current_entry);
|
||||
|
||||
if (callchain_param.mode == CHAIN_GRAPH_REL)
|
||||
new_total = child->children_hit;
|
||||
else
|
||||
new_total = total;
|
||||
|
||||
row += hist_browser__show_callchain(browser, &child->rb_root,
|
||||
new_level,
|
||||
row, row_offset,
|
||||
new_total,
|
||||
is_current_entry);
|
||||
}
|
||||
if (row == browser->b.rows)
|
||||
goto out;
|
||||
break;
|
||||
node = next;
|
||||
}
|
||||
out:
|
||||
return row - first_row;
|
||||
}
|
||||
|
||||
static int hist_browser__show_callchain_node(struct hist_browser *browser,
|
||||
struct callchain_node *node,
|
||||
int level, unsigned short row,
|
||||
off_t *row_offset,
|
||||
bool *is_current_entry)
|
||||
{
|
||||
struct callchain_list *chain;
|
||||
int first_row = row;
|
||||
int offset = level * LEVEL_OFFSET_STEP;
|
||||
char folded_sign = ' ';
|
||||
|
||||
list_for_each_entry(chain, &node->val, list) {
|
||||
char bf[1024], *s;
|
||||
|
||||
folded_sign = callchain_list__folded(chain);
|
||||
|
||||
if (*row_offset != 0) {
|
||||
--*row_offset;
|
||||
continue;
|
||||
}
|
||||
|
||||
s = callchain_list__sym_name(chain, bf, sizeof(bf),
|
||||
browser->show_dso);
|
||||
hist_browser__show_callchain_entry(browser, chain, row,
|
||||
offset, folded_sign, s,
|
||||
is_current_entry);
|
||||
|
||||
if (++row == browser->b.rows)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (folded_sign == '-')
|
||||
row += hist_browser__show_callchain_node_rb_tree(browser, node,
|
||||
browser->hists->stats.total_period,
|
||||
level + 1, row,
|
||||
row_offset,
|
||||
is_current_entry);
|
||||
out:
|
||||
return row - first_row;
|
||||
}
|
||||
|
||||
static int hist_browser__show_callchain(struct hist_browser *browser,
|
||||
struct rb_root *chain,
|
||||
int level, unsigned short row,
|
||||
off_t *row_offset,
|
||||
bool *is_current_entry)
|
||||
{
|
||||
struct rb_node *nd;
|
||||
int first_row = row;
|
||||
|
||||
for (nd = rb_first(chain); nd; nd = rb_next(nd)) {
|
||||
struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
|
||||
|
||||
row += hist_browser__show_callchain_node(browser, node, level,
|
||||
row, row_offset,
|
||||
is_current_entry);
|
||||
if (row == browser->b.rows)
|
||||
break;
|
||||
}
|
||||
|
||||
return row - first_row;
|
||||
}
|
||||
|
||||
struct hpp_arg {
|
||||
struct ui_browser *b;
|
||||
char folded_sign;
|
||||
|
@ -817,9 +756,16 @@ static int hist_browser__show_entry(struct hist_browser *browser,
|
|||
--row_offset;
|
||||
|
||||
if (folded_sign == '-' && row != browser->b.rows) {
|
||||
printed += hist_browser__show_callchain(browser, &entry->sorted_chain,
|
||||
u64 total = hists__total_period(entry->hists);
|
||||
|
||||
if (symbol_conf.cumulate_callchain)
|
||||
total = entry->stat_acc->period;
|
||||
|
||||
printed += hist_browser__show_callchain(browser,
|
||||
&entry->sorted_chain,
|
||||
1, row, &row_offset,
|
||||
¤t_entry);
|
||||
total, ¤t_entry);
|
||||
|
||||
if (current_entry)
|
||||
browser->he_selection = entry;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue