diff options
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r-- | tools/perf/util/hist.c | 115 |
1 files changed, 79 insertions, 36 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index d998d1d706eb..0bc67900352c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -16,6 +16,50 @@ struct callchain_param callchain_param = { | |||
16 | .min_percent = 0.5 | 16 | .min_percent = 0.5 |
17 | }; | 17 | }; |
18 | 18 | ||
19 | u16 hists__col_len(struct hists *self, enum hist_column col) | ||
20 | { | ||
21 | return self->col_len[col]; | ||
22 | } | ||
23 | |||
24 | void hists__set_col_len(struct hists *self, enum hist_column col, u16 len) | ||
25 | { | ||
26 | self->col_len[col] = len; | ||
27 | } | ||
28 | |||
29 | bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len) | ||
30 | { | ||
31 | if (len > hists__col_len(self, col)) { | ||
32 | hists__set_col_len(self, col, len); | ||
33 | return true; | ||
34 | } | ||
35 | return false; | ||
36 | } | ||
37 | |||
38 | static void hists__reset_col_len(struct hists *self) | ||
39 | { | ||
40 | enum hist_column col; | ||
41 | |||
42 | for (col = 0; col < HISTC_NR_COLS; ++col) | ||
43 | hists__set_col_len(self, col, 0); | ||
44 | } | ||
45 | |||
46 | static void hists__calc_col_len(struct hists *self, struct hist_entry *h) | ||
47 | { | ||
48 | u16 len; | ||
49 | |||
50 | if (h->ms.sym) | ||
51 | hists__new_col_len(self, HISTC_SYMBOL, h->ms.sym->namelen); | ||
52 | |||
53 | len = thread__comm_len(h->thread); | ||
54 | if (hists__new_col_len(self, HISTC_COMM, len)) | ||
55 | hists__set_col_len(self, HISTC_THREAD, len + 6); | ||
56 | |||
57 | if (h->ms.map) { | ||
58 | len = dso__name_len(h->ms.map->dso); | ||
59 | hists__new_col_len(self, HISTC_DSO, len); | ||
60 | } | ||
61 | } | ||
62 | |||
19 | static void hist_entry__add_cpumode_period(struct hist_entry *self, | 63 | static void hist_entry__add_cpumode_period(struct hist_entry *self, |
20 | unsigned int cpumode, u64 period) | 64 | unsigned int cpumode, u64 period) |
21 | { | 65 | { |
@@ -56,13 +100,12 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) | |||
56 | return self; | 100 | return self; |
57 | } | 101 | } |
58 | 102 | ||
59 | static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry) | 103 | static void hists__inc_nr_entries(struct hists *self, struct hist_entry *h) |
60 | { | 104 | { |
61 | if (entry->filtered) | 105 | if (!h->filtered) { |
62 | return; | 106 | hists__calc_col_len(self, h); |
63 | if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen) | 107 | ++self->nr_entries; |
64 | self->max_sym_namelen = entry->ms.sym->namelen; | 108 | } |
65 | ++self->nr_entries; | ||
66 | } | 109 | } |
67 | 110 | ||
68 | static u8 symbol__parent_filter(const struct symbol *parent) | 111 | static u8 symbol__parent_filter(const struct symbol *parent) |
@@ -208,7 +251,7 @@ void hists__collapse_resort(struct hists *self) | |||
208 | tmp = RB_ROOT; | 251 | tmp = RB_ROOT; |
209 | next = rb_first(&self->entries); | 252 | next = rb_first(&self->entries); |
210 | self->nr_entries = 0; | 253 | self->nr_entries = 0; |
211 | self->max_sym_namelen = 0; | 254 | hists__reset_col_len(self); |
212 | 255 | ||
213 | while (next) { | 256 | while (next) { |
214 | n = rb_entry(next, struct hist_entry, rb_node); | 257 | n = rb_entry(next, struct hist_entry, rb_node); |
@@ -265,7 +308,7 @@ void hists__output_resort(struct hists *self) | |||
265 | next = rb_first(&self->entries); | 308 | next = rb_first(&self->entries); |
266 | 309 | ||
267 | self->nr_entries = 0; | 310 | self->nr_entries = 0; |
268 | self->max_sym_namelen = 0; | 311 | hists__reset_col_len(self); |
269 | 312 | ||
270 | while (next) { | 313 | while (next) { |
271 | n = rb_entry(next, struct hist_entry, rb_node); | 314 | n = rb_entry(next, struct hist_entry, rb_node); |
@@ -532,8 +575,9 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
532 | } | 575 | } |
533 | 576 | ||
534 | int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, | 577 | int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, |
535 | struct hists *pair_hists, bool show_displacement, | 578 | struct hists *hists, struct hists *pair_hists, |
536 | long displacement, bool color, u64 session_total) | 579 | bool show_displacement, long displacement, |
580 | bool color, u64 session_total) | ||
537 | { | 581 | { |
538 | struct sort_entry *se; | 582 | struct sort_entry *se; |
539 | u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; | 583 | u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; |
@@ -637,24 +681,25 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, | |||
637 | 681 | ||
638 | ret += snprintf(s + ret, size - ret, "%s", sep ?: " "); | 682 | ret += snprintf(s + ret, size - ret, "%s", sep ?: " "); |
639 | ret += se->se_snprintf(self, s + ret, size - ret, | 683 | ret += se->se_snprintf(self, s + ret, size - ret, |
640 | se->se_width ? *se->se_width : 0); | 684 | hists__col_len(hists, se->se_width_idx)); |
641 | } | 685 | } |
642 | 686 | ||
643 | return ret; | 687 | return ret; |
644 | } | 688 | } |
645 | 689 | ||
646 | int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists, | 690 | int hist_entry__fprintf(struct hist_entry *self, struct hists *hists, |
647 | bool show_displacement, long displacement, FILE *fp, | 691 | struct hists *pair_hists, bool show_displacement, |
648 | u64 session_total) | 692 | long displacement, FILE *fp, u64 session_total) |
649 | { | 693 | { |
650 | char bf[512]; | 694 | char bf[512]; |
651 | hist_entry__snprintf(self, bf, sizeof(bf), pair_hists, | 695 | hist_entry__snprintf(self, bf, sizeof(bf), hists, pair_hists, |
652 | show_displacement, displacement, | 696 | show_displacement, displacement, |
653 | true, session_total); | 697 | true, session_total); |
654 | return fprintf(fp, "%s\n", bf); | 698 | return fprintf(fp, "%s\n", bf); |
655 | } | 699 | } |
656 | 700 | ||
657 | static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, | 701 | static size_t hist_entry__fprintf_callchain(struct hist_entry *self, |
702 | struct hists *hists, FILE *fp, | ||
658 | u64 session_total) | 703 | u64 session_total) |
659 | { | 704 | { |
660 | int left_margin = 0; | 705 | int left_margin = 0; |
@@ -662,7 +707,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, | |||
662 | if (sort__first_dimension == SORT_COMM) { | 707 | if (sort__first_dimension == SORT_COMM) { |
663 | struct sort_entry *se = list_first_entry(&hist_entry__sort_list, | 708 | struct sort_entry *se = list_first_entry(&hist_entry__sort_list, |
664 | typeof(*se), list); | 709 | typeof(*se), list); |
665 | left_margin = se->se_width ? *se->se_width : 0; | 710 | left_margin = hists__col_len(hists, se->se_width_idx); |
666 | left_margin -= thread__comm_len(self->thread); | 711 | left_margin -= thread__comm_len(self->thread); |
667 | } | 712 | } |
668 | 713 | ||
@@ -733,17 +778,17 @@ size_t hists__fprintf(struct hists *self, struct hists *pair, | |||
733 | continue; | 778 | continue; |
734 | } | 779 | } |
735 | width = strlen(se->se_header); | 780 | width = strlen(se->se_header); |
736 | if (se->se_width) { | 781 | if (symbol_conf.col_width_list_str) { |
737 | if (symbol_conf.col_width_list_str) { | 782 | if (col_width) { |
738 | if (col_width) { | 783 | hists__set_col_len(self, se->se_width_idx, |
739 | *se->se_width = atoi(col_width); | 784 | atoi(col_width)); |
740 | col_width = strchr(col_width, ','); | 785 | col_width = strchr(col_width, ','); |
741 | if (col_width) | 786 | if (col_width) |
742 | ++col_width; | 787 | ++col_width; |
743 | } | ||
744 | } | 788 | } |
745 | width = *se->se_width = max(*se->se_width, width); | ||
746 | } | 789 | } |
790 | if (!hists__new_col_len(self, se->se_width_idx, width)) | ||
791 | width = hists__col_len(self, se->se_width_idx); | ||
747 | fprintf(fp, " %*s", width, se->se_header); | 792 | fprintf(fp, " %*s", width, se->se_header); |
748 | } | 793 | } |
749 | fprintf(fp, "\n"); | 794 | fprintf(fp, "\n"); |
@@ -766,9 +811,8 @@ size_t hists__fprintf(struct hists *self, struct hists *pair, | |||
766 | continue; | 811 | continue; |
767 | 812 | ||
768 | fprintf(fp, " "); | 813 | fprintf(fp, " "); |
769 | if (se->se_width) | 814 | width = hists__col_len(self, se->se_width_idx); |
770 | width = *se->se_width; | 815 | if (width == 0) |
771 | else | ||
772 | width = strlen(se->se_header); | 816 | width = strlen(se->se_header); |
773 | for (i = 0; i < width; i++) | 817 | for (i = 0; i < width; i++) |
774 | fprintf(fp, "."); | 818 | fprintf(fp, "."); |
@@ -788,12 +832,12 @@ print_entries: | |||
788 | displacement = 0; | 832 | displacement = 0; |
789 | ++position; | 833 | ++position; |
790 | } | 834 | } |
791 | ret += hist_entry__fprintf(h, pair, show_displacement, | 835 | ret += hist_entry__fprintf(h, self, pair, show_displacement, |
792 | displacement, fp, self->stats.total_period); | 836 | displacement, fp, self->stats.total_period); |
793 | 837 | ||
794 | if (symbol_conf.use_callchain) | 838 | if (symbol_conf.use_callchain) |
795 | ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period); | 839 | ret += hist_entry__fprintf_callchain(h, self, fp, |
796 | 840 | self->stats.total_period); | |
797 | if (h->ms.map == NULL && verbose > 1) { | 841 | if (h->ms.map == NULL && verbose > 1) { |
798 | __map_groups__fprintf_maps(&h->thread->mg, | 842 | __map_groups__fprintf_maps(&h->thread->mg, |
799 | MAP__FUNCTION, verbose, fp); | 843 | MAP__FUNCTION, verbose, fp); |
@@ -817,8 +861,7 @@ static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h, | |||
817 | self->stats.total_period += h->period; | 861 | self->stats.total_period += h->period; |
818 | self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; | 862 | self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; |
819 | 863 | ||
820 | if (h->ms.sym && self->max_sym_namelen < h->ms.sym->namelen) | 864 | hists__calc_col_len(self, h); |
821 | self->max_sym_namelen = h->ms.sym->namelen; | ||
822 | } | 865 | } |
823 | 866 | ||
824 | void hists__filter_by_dso(struct hists *self, const struct dso *dso) | 867 | void hists__filter_by_dso(struct hists *self, const struct dso *dso) |
@@ -827,7 +870,7 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso) | |||
827 | 870 | ||
828 | self->nr_entries = self->stats.total_period = 0; | 871 | self->nr_entries = self->stats.total_period = 0; |
829 | self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; | 872 | self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; |
830 | self->max_sym_namelen = 0; | 873 | hists__reset_col_len(self); |
831 | 874 | ||
832 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | 875 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { |
833 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 876 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
@@ -850,7 +893,7 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread) | |||
850 | 893 | ||
851 | self->nr_entries = self->stats.total_period = 0; | 894 | self->nr_entries = self->stats.total_period = 0; |
852 | self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; | 895 | self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; |
853 | self->max_sym_namelen = 0; | 896 | hists__reset_col_len(self); |
854 | 897 | ||
855 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | 898 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { |
856 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 899 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |