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, |
