aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2010-08-22 14:05:22 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2010-08-22 14:43:17 -0400
commitd2009c5130b627d3efccae8ed36cd43450c8486d (patch)
tree22afece12b12600d9132ab76f8fe74425548351d /tools
parentf4e7ac0a233a4dc9b51345546ab69c64bb43e2c1 (diff)
perf: Keep track of the max depth of a callchain
In order to implement callchains collapsing, we need to keep track of the maximum depth in a histogram tree of callchains. This way we'll avoid allocating an arbitrary temporary buffer size on callchain merge time. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Christoph Hellwig <hch@infradead.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/callchain.c23
-rw-r--r--tools/perf/util/callchain.h22
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/sort.h2
4 files changed, 29 insertions, 20 deletions
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index f231f43424d2..f0b23f309edc 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -86,10 +86,10 @@ __sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
86 * sort them by hit 86 * sort them by hit
87 */ 87 */
88static void 88static void
89sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node, 89sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root,
90 u64 min_hit, struct callchain_param *param __used) 90 u64 min_hit, struct callchain_param *param __used)
91{ 91{
92 __sort_chain_flat(rb_root, node, min_hit); 92 __sort_chain_flat(rb_root, &root->node, min_hit);
93} 93}
94 94
95static void __sort_chain_graph_abs(struct callchain_node *node, 95static void __sort_chain_graph_abs(struct callchain_node *node,
@@ -108,11 +108,11 @@ static void __sort_chain_graph_abs(struct callchain_node *node,
108} 108}
109 109
110static void 110static void
111sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_node *chain_root, 111sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_root *chain_root,
112 u64 min_hit, struct callchain_param *param __used) 112 u64 min_hit, struct callchain_param *param __used)
113{ 113{
114 __sort_chain_graph_abs(chain_root, min_hit); 114 __sort_chain_graph_abs(&chain_root->node, min_hit);
115 rb_root->rb_node = chain_root->rb_root.rb_node; 115 rb_root->rb_node = chain_root->node.rb_root.rb_node;
116} 116}
117 117
118static void __sort_chain_graph_rel(struct callchain_node *node, 118static void __sort_chain_graph_rel(struct callchain_node *node,
@@ -133,11 +133,11 @@ static void __sort_chain_graph_rel(struct callchain_node *node,
133} 133}
134 134
135static void 135static void
136sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, 136sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_root *chain_root,
137 u64 min_hit __used, struct callchain_param *param) 137 u64 min_hit __used, struct callchain_param *param)
138{ 138{
139 __sort_chain_graph_rel(chain_root, param->min_percent / 100.0); 139 __sort_chain_graph_rel(&chain_root->node, param->min_percent / 100.0);
140 rb_root->rb_node = chain_root->rb_root.rb_node; 140 rb_root->rb_node = chain_root->node.rb_root.rb_node;
141} 141}
142 142
143int register_callchain_param(struct callchain_param *param) 143int register_callchain_param(struct callchain_param *param)
@@ -380,7 +380,7 @@ static void filter_context(struct ip_callchain *old, struct resolved_chain *new,
380} 380}
381 381
382 382
383int append_chain(struct callchain_node *root, struct ip_callchain *chain, 383int append_chain(struct callchain_root *root, struct ip_callchain *chain,
384 struct map_symbol *syms, u64 period) 384 struct map_symbol *syms, u64 period)
385{ 385{
386 struct resolved_chain *filtered; 386 struct resolved_chain *filtered;
@@ -398,7 +398,10 @@ int append_chain(struct callchain_node *root, struct ip_callchain *chain,
398 if (!filtered->nr) 398 if (!filtered->nr)
399 goto end; 399 goto end;
400 400
401 __append_chain_children(root, filtered, 0, period); 401 __append_chain_children(&root->node, filtered, 0, period);
402
403 if (filtered->nr > root->max_depth)
404 root->max_depth = filtered->nr;
402end: 405end:
403 free(filtered); 406 free(filtered);
404 407
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 624a96c636fd..9b93a38e88ec 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -26,9 +26,14 @@ struct callchain_node {
26 u64 children_hit; 26 u64 children_hit;
27}; 27};
28 28
29struct callchain_root {
30 u64 max_depth;
31 struct callchain_node node;
32};
33
29struct callchain_param; 34struct callchain_param;
30 35
31typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *, 36typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *,
32 u64, struct callchain_param *); 37 u64, struct callchain_param *);
33 38
34struct callchain_param { 39struct callchain_param {
@@ -44,14 +49,15 @@ struct callchain_list {
44 struct list_head list; 49 struct list_head list;
45}; 50};
46 51
47static inline void callchain_init(struct callchain_node *node) 52static inline void callchain_init(struct callchain_root *root)
48{ 53{
49 INIT_LIST_HEAD(&node->brothers); 54 INIT_LIST_HEAD(&root->node.brothers);
50 INIT_LIST_HEAD(&node->children); 55 INIT_LIST_HEAD(&root->node.children);
51 INIT_LIST_HEAD(&node->val); 56 INIT_LIST_HEAD(&root->node.val);
52 57
53 node->parent = NULL; 58 root->node.parent = NULL;
54 node->hit = 0; 59 root->node.hit = 0;
60 root->max_depth = 0;
55} 61}
56 62
57static inline u64 cumul_hits(struct callchain_node *node) 63static inline u64 cumul_hits(struct callchain_node *node)
@@ -60,7 +66,7 @@ static inline u64 cumul_hits(struct callchain_node *node)
60} 66}
61 67
62int register_callchain_param(struct callchain_param *param); 68int register_callchain_param(struct callchain_param *param);
63int append_chain(struct callchain_node *root, struct ip_callchain *chain, 69int append_chain(struct callchain_root *root, struct ip_callchain *chain,
64 struct map_symbol *syms, u64 period); 70 struct map_symbol *syms, u64 period);
65 71
66bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event); 72bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index be22ae6ef055..e77ff772463e 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -87,7 +87,7 @@ static void hist_entry__add_cpumode_period(struct hist_entry *self,
87 87
88static struct hist_entry *hist_entry__new(struct hist_entry *template) 88static struct hist_entry *hist_entry__new(struct hist_entry *template)
89{ 89{
90 size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_node) : 0; 90 size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0;
91 struct hist_entry *self = malloc(sizeof(*self) + callchain_size); 91 struct hist_entry *self = malloc(sizeof(*self) + callchain_size);
92 92
93 if (self != NULL) { 93 if (self != NULL) {
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 46e531d09e8b..0b91053a7d11 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -70,7 +70,7 @@ struct hist_entry {
70 struct hist_entry *pair; 70 struct hist_entry *pair;
71 struct rb_root sorted_chain; 71 struct rb_root sorted_chain;
72 }; 72 };
73 struct callchain_node callchain[0]; 73 struct callchain_root callchain[0];
74}; 74};
75 75
76enum sort_type { 76enum sort_type {