4 struct rb_root collapse_hists
;
5 struct rb_root output_hists
;
8 struct callchain_param callchain_param
= {
9 .mode
= CHAIN_GRAPH_REL
,
14 unsigned long total_mmap
;
15 unsigned long total_comm
;
16 unsigned long total_fork
;
17 unsigned long total_unknown
;
18 unsigned long total_lost
;
21 * histogram, sorted on item, collects counts
24 struct hist_entry
*__hist_entry__add(struct thread
*thread
, struct map
*map
,
26 struct symbol
*sym_parent
,
27 u64 ip
, u64 count
, char level
, bool *hit
)
29 struct rb_node
**p
= &hist
.rb_node
;
30 struct rb_node
*parent
= NULL
;
31 struct hist_entry
*he
;
32 struct hist_entry entry
= {
45 he
= rb_entry(parent
, struct hist_entry
, rb_node
);
47 cmp
= hist_entry__cmp(&entry
, he
);
60 he
= malloc(sizeof(*he
));
64 rb_link_node(&he
->rb_node
, parent
, p
);
65 rb_insert_color(&he
->rb_node
, &hist
);
71 hist_entry__cmp(struct hist_entry
*left
, struct hist_entry
*right
)
73 struct sort_entry
*se
;
76 list_for_each_entry(se
, &hist_entry__sort_list
, list
) {
77 cmp
= se
->cmp(left
, right
);
86 hist_entry__collapse(struct hist_entry
*left
, struct hist_entry
*right
)
88 struct sort_entry
*se
;
91 list_for_each_entry(se
, &hist_entry__sort_list
, list
) {
92 int64_t (*f
)(struct hist_entry
*, struct hist_entry
*);
94 f
= se
->collapse
?: se
->cmp
;
104 void hist_entry__free(struct hist_entry
*he
)
110 * collapse the histogram
113 void collapse__insert_entry(struct hist_entry
*he
)
115 struct rb_node
**p
= &collapse_hists
.rb_node
;
116 struct rb_node
*parent
= NULL
;
117 struct hist_entry
*iter
;
122 iter
= rb_entry(parent
, struct hist_entry
, rb_node
);
124 cmp
= hist_entry__collapse(iter
, he
);
127 iter
->count
+= he
->count
;
128 hist_entry__free(he
);
138 rb_link_node(&he
->rb_node
, parent
, p
);
139 rb_insert_color(&he
->rb_node
, &collapse_hists
);
142 void collapse__resort(void)
144 struct rb_node
*next
;
145 struct hist_entry
*n
;
147 if (!sort__need_collapse
)
150 next
= rb_first(&hist
);
152 n
= rb_entry(next
, struct hist_entry
, rb_node
);
153 next
= rb_next(&n
->rb_node
);
155 rb_erase(&n
->rb_node
, &hist
);
156 collapse__insert_entry(n
);
161 * reverse the map, sort on count.
164 void output__insert_entry(struct hist_entry
*he
, u64 min_callchain_hits
)
166 struct rb_node
**p
= &output_hists
.rb_node
;
167 struct rb_node
*parent
= NULL
;
168 struct hist_entry
*iter
;
171 callchain_param
.sort(&he
->sorted_chain
, &he
->callchain
,
172 min_callchain_hits
, &callchain_param
);
176 iter
= rb_entry(parent
, struct hist_entry
, rb_node
);
178 if (he
->count
> iter
->count
)
184 rb_link_node(&he
->rb_node
, parent
, p
);
185 rb_insert_color(&he
->rb_node
, &output_hists
);
188 void output__resort(u64 total_samples
)
190 struct rb_node
*next
;
191 struct hist_entry
*n
;
192 struct rb_root
*tree
= &hist
;
193 u64 min_callchain_hits
;
196 total_samples
* (callchain_param
.min_percent
/ 100);
198 if (sort__need_collapse
)
199 tree
= &collapse_hists
;
201 next
= rb_first(tree
);
204 n
= rb_entry(next
, struct hist_entry
, rb_node
);
205 next
= rb_next(&n
->rb_node
);
207 rb_erase(&n
->rb_node
, tree
);
208 output__insert_entry(n
, min_callchain_hits
);