diff options
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r-- | tools/perf/util/hist.c | 92 |
1 files changed, 41 insertions, 51 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0f154a530dfd..410cf56c9662 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -8,21 +8,21 @@ struct callchain_param callchain_param = { | |||
8 | .min_percent = 0.5 | 8 | .min_percent = 0.5 |
9 | }; | 9 | }; |
10 | 10 | ||
11 | static void perf_session__add_cpumode_count(struct hist_entry *he, | 11 | static void hist_entry__add_cpumode_count(struct hist_entry *self, |
12 | unsigned int cpumode, u64 count) | 12 | unsigned int cpumode, u64 count) |
13 | { | 13 | { |
14 | switch (cpumode) { | 14 | switch (cpumode) { |
15 | case PERF_RECORD_MISC_KERNEL: | 15 | case PERF_RECORD_MISC_KERNEL: |
16 | he->count_sys += count; | 16 | self->count_sys += count; |
17 | break; | 17 | break; |
18 | case PERF_RECORD_MISC_USER: | 18 | case PERF_RECORD_MISC_USER: |
19 | he->count_us += count; | 19 | self->count_us += count; |
20 | break; | 20 | break; |
21 | case PERF_RECORD_MISC_GUEST_KERNEL: | 21 | case PERF_RECORD_MISC_GUEST_KERNEL: |
22 | he->count_guest_sys += count; | 22 | self->count_guest_sys += count; |
23 | break; | 23 | break; |
24 | case PERF_RECORD_MISC_GUEST_USER: | 24 | case PERF_RECORD_MISC_GUEST_USER: |
25 | he->count_guest_us += count; | 25 | self->count_guest_us += count; |
26 | break; | 26 | break; |
27 | default: | 27 | default: |
28 | break; | 28 | break; |
@@ -47,12 +47,11 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) | |||
47 | return self; | 47 | return self; |
48 | } | 48 | } |
49 | 49 | ||
50 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | 50 | struct hist_entry *__hists__add_entry(struct hists *self, |
51 | struct addr_location *al, | 51 | struct addr_location *al, |
52 | struct symbol *sym_parent, | 52 | struct symbol *sym_parent, u64 count) |
53 | u64 count) | ||
54 | { | 53 | { |
55 | struct rb_node **p = &hists->rb_node; | 54 | struct rb_node **p = &self->entries.rb_node; |
56 | struct rb_node *parent = NULL; | 55 | struct rb_node *parent = NULL; |
57 | struct hist_entry *he; | 56 | struct hist_entry *he; |
58 | struct hist_entry entry = { | 57 | struct hist_entry entry = { |
@@ -89,9 +88,9 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
89 | if (!he) | 88 | if (!he) |
90 | return NULL; | 89 | return NULL; |
91 | rb_link_node(&he->rb_node, parent, p); | 90 | rb_link_node(&he->rb_node, parent, p); |
92 | rb_insert_color(&he->rb_node, hists); | 91 | rb_insert_color(&he->rb_node, &self->entries); |
93 | out: | 92 | out: |
94 | perf_session__add_cpumode_count(he, al->cpumode, count); | 93 | hist_entry__add_cpumode_count(he, al->cpumode, count); |
95 | return he; | 94 | return he; |
96 | } | 95 | } |
97 | 96 | ||
@@ -167,7 +166,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he) | |||
167 | rb_insert_color(&he->rb_node, root); | 166 | rb_insert_color(&he->rb_node, root); |
168 | } | 167 | } |
169 | 168 | ||
170 | void perf_session__collapse_resort(struct rb_root *hists) | 169 | void hists__collapse_resort(struct hists *self) |
171 | { | 170 | { |
172 | struct rb_root tmp; | 171 | struct rb_root tmp; |
173 | struct rb_node *next; | 172 | struct rb_node *next; |
@@ -177,28 +176,28 @@ void perf_session__collapse_resort(struct rb_root *hists) | |||
177 | return; | 176 | return; |
178 | 177 | ||
179 | tmp = RB_ROOT; | 178 | tmp = RB_ROOT; |
180 | next = rb_first(hists); | 179 | next = rb_first(&self->entries); |
181 | 180 | ||
182 | while (next) { | 181 | while (next) { |
183 | n = rb_entry(next, struct hist_entry, rb_node); | 182 | n = rb_entry(next, struct hist_entry, rb_node); |
184 | next = rb_next(&n->rb_node); | 183 | next = rb_next(&n->rb_node); |
185 | 184 | ||
186 | rb_erase(&n->rb_node, hists); | 185 | rb_erase(&n->rb_node, &self->entries); |
187 | collapse__insert_entry(&tmp, n); | 186 | collapse__insert_entry(&tmp, n); |
188 | } | 187 | } |
189 | 188 | ||
190 | *hists = tmp; | 189 | self->entries = tmp; |
191 | } | 190 | } |
192 | 191 | ||
193 | /* | 192 | /* |
194 | * reverse the map, sort on count. | 193 | * reverse the map, sort on count. |
195 | */ | 194 | */ |
196 | 195 | ||
197 | static void perf_session__insert_output_hist_entry(struct rb_root *root, | 196 | static void __hists__insert_output_entry(struct rb_root *entries, |
198 | struct hist_entry *he, | 197 | struct hist_entry *he, |
199 | u64 min_callchain_hits) | 198 | u64 min_callchain_hits) |
200 | { | 199 | { |
201 | struct rb_node **p = &root->rb_node; | 200 | struct rb_node **p = &entries->rb_node; |
202 | struct rb_node *parent = NULL; | 201 | struct rb_node *parent = NULL; |
203 | struct hist_entry *iter; | 202 | struct hist_entry *iter; |
204 | 203 | ||
@@ -217,10 +216,10 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root, | |||
217 | } | 216 | } |
218 | 217 | ||
219 | rb_link_node(&he->rb_node, parent, p); | 218 | rb_link_node(&he->rb_node, parent, p); |
220 | rb_insert_color(&he->rb_node, root); | 219 | rb_insert_color(&he->rb_node, entries); |
221 | } | 220 | } |
222 | 221 | ||
223 | u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples) | 222 | u64 hists__output_resort(struct hists *self) |
224 | { | 223 | { |
225 | struct rb_root tmp; | 224 | struct rb_root tmp; |
226 | struct rb_node *next; | 225 | struct rb_node *next; |
@@ -228,23 +227,21 @@ u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples) | |||
228 | u64 min_callchain_hits; | 227 | u64 min_callchain_hits; |
229 | u64 nr_hists = 0; | 228 | u64 nr_hists = 0; |
230 | 229 | ||
231 | min_callchain_hits = | 230 | min_callchain_hits = self->stats.total * (callchain_param.min_percent / 100); |
232 | total_samples * (callchain_param.min_percent / 100); | ||
233 | 231 | ||
234 | tmp = RB_ROOT; | 232 | tmp = RB_ROOT; |
235 | next = rb_first(hists); | 233 | next = rb_first(&self->entries); |
236 | 234 | ||
237 | while (next) { | 235 | while (next) { |
238 | n = rb_entry(next, struct hist_entry, rb_node); | 236 | n = rb_entry(next, struct hist_entry, rb_node); |
239 | next = rb_next(&n->rb_node); | 237 | next = rb_next(&n->rb_node); |
240 | 238 | ||
241 | rb_erase(&n->rb_node, hists); | 239 | rb_erase(&n->rb_node, &self->entries); |
242 | perf_session__insert_output_hist_entry(&tmp, n, | 240 | __hists__insert_output_entry(&tmp, n, min_callchain_hits); |
243 | min_callchain_hits); | ||
244 | ++nr_hists; | 241 | ++nr_hists; |
245 | } | 242 | } |
246 | 243 | ||
247 | *hists = tmp; | 244 | self->entries = tmp; |
248 | return nr_hists; | 245 | return nr_hists; |
249 | } | 246 | } |
250 | 247 | ||
@@ -500,12 +497,9 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
500 | return ret; | 497 | return ret; |
501 | } | 498 | } |
502 | 499 | ||
503 | int hist_entry__snprintf(struct hist_entry *self, | 500 | int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, |
504 | char *s, size_t size, | 501 | struct hists *pair_hists, bool show_displacement, |
505 | struct perf_session *pair_session, | 502 | long displacement, bool color, u64 session_total) |
506 | bool show_displacement, | ||
507 | long displacement, bool color, | ||
508 | u64 session_total) | ||
509 | { | 503 | { |
510 | struct sort_entry *se; | 504 | struct sort_entry *se; |
511 | u64 count, total, count_sys, count_us, count_guest_sys, count_guest_us; | 505 | u64 count, total, count_sys, count_us, count_guest_sys, count_guest_us; |
@@ -515,9 +509,9 @@ int hist_entry__snprintf(struct hist_entry *self, | |||
515 | if (symbol_conf.exclude_other && !self->parent) | 509 | if (symbol_conf.exclude_other && !self->parent) |
516 | return 0; | 510 | return 0; |
517 | 511 | ||
518 | if (pair_session) { | 512 | if (pair_hists) { |
519 | count = self->pair ? self->pair->count : 0; | 513 | count = self->pair ? self->pair->count : 0; |
520 | total = pair_session->events_stats.total; | 514 | total = pair_hists->stats.total; |
521 | count_sys = self->pair ? self->pair->count_sys : 0; | 515 | count_sys = self->pair ? self->pair->count_sys : 0; |
522 | count_us = self->pair ? self->pair->count_us : 0; | 516 | count_us = self->pair ? self->pair->count_us : 0; |
523 | count_guest_sys = self->pair ? self->pair->count_guest_sys : 0; | 517 | count_guest_sys = self->pair ? self->pair->count_guest_sys : 0; |
@@ -569,7 +563,7 @@ int hist_entry__snprintf(struct hist_entry *self, | |||
569 | ret += snprintf(s + ret, size - ret, "%11lld", count); | 563 | ret += snprintf(s + ret, size - ret, "%11lld", count); |
570 | } | 564 | } |
571 | 565 | ||
572 | if (pair_session) { | 566 | if (pair_hists) { |
573 | char bf[32]; | 567 | char bf[32]; |
574 | double old_percent = 0, new_percent = 0, diff; | 568 | double old_percent = 0, new_percent = 0, diff; |
575 | 569 | ||
@@ -615,14 +609,12 @@ int hist_entry__snprintf(struct hist_entry *self, | |||
615 | return ret; | 609 | return ret; |
616 | } | 610 | } |
617 | 611 | ||
618 | int hist_entry__fprintf(struct hist_entry *self, | 612 | int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists, |
619 | struct perf_session *pair_session, | 613 | bool show_displacement, long displacement, FILE *fp, |
620 | bool show_displacement, | ||
621 | long displacement, FILE *fp, | ||
622 | u64 session_total) | 614 | u64 session_total) |
623 | { | 615 | { |
624 | char bf[512]; | 616 | char bf[512]; |
625 | hist_entry__snprintf(self, bf, sizeof(bf), pair_session, | 617 | hist_entry__snprintf(self, bf, sizeof(bf), pair_hists, |
626 | show_displacement, displacement, | 618 | show_displacement, displacement, |
627 | true, session_total); | 619 | true, session_total); |
628 | return fprintf(fp, "%s\n", bf); | 620 | return fprintf(fp, "%s\n", bf); |
@@ -644,10 +636,8 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, | |||
644 | left_margin); | 636 | left_margin); |
645 | } | 637 | } |
646 | 638 | ||
647 | size_t perf_session__fprintf_hists(struct rb_root *hists, | 639 | size_t hists__fprintf(struct hists *self, struct hists *pair, |
648 | struct perf_session *pair, | 640 | bool show_displacement, FILE *fp) |
649 | bool show_displacement, FILE *fp, | ||
650 | u64 session_total) | ||
651 | { | 641 | { |
652 | struct sort_entry *se; | 642 | struct sort_entry *se; |
653 | struct rb_node *nd; | 643 | struct rb_node *nd; |
@@ -753,7 +743,7 @@ size_t perf_session__fprintf_hists(struct rb_root *hists, | |||
753 | fprintf(fp, "\n#\n"); | 743 | fprintf(fp, "\n#\n"); |
754 | 744 | ||
755 | print_entries: | 745 | print_entries: |
756 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { | 746 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { |
757 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 747 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
758 | 748 | ||
759 | if (show_displacement) { | 749 | if (show_displacement) { |
@@ -765,10 +755,10 @@ print_entries: | |||
765 | ++position; | 755 | ++position; |
766 | } | 756 | } |
767 | ret += hist_entry__fprintf(h, pair, show_displacement, | 757 | ret += hist_entry__fprintf(h, pair, show_displacement, |
768 | displacement, fp, session_total); | 758 | displacement, fp, self->stats.total); |
769 | 759 | ||
770 | if (symbol_conf.use_callchain) | 760 | if (symbol_conf.use_callchain) |
771 | ret += hist_entry__fprintf_callchain(h, fp, session_total); | 761 | ret += hist_entry__fprintf_callchain(h, fp, self->stats.total); |
772 | 762 | ||
773 | if (h->ms.map == NULL && verbose > 1) { | 763 | if (h->ms.map == NULL && verbose > 1) { |
774 | __map_groups__fprintf_maps(&h->thread->mg, | 764 | __map_groups__fprintf_maps(&h->thread->mg, |