aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/hist.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r--tools/perf/util/hist.c115
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
19u16 hists__col_len(struct hists *self, enum hist_column col)
20{
21 return self->col_len[col];
22}
23
24void hists__set_col_len(struct hists *self, enum hist_column col, u16 len)
25{
26 self->col_len[col] = len;
27}
28
29bool 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
38static 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
46static 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
19static void hist_entry__add_cpumode_period(struct hist_entry *self, 63static 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
59static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry) 103static 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
68static u8 symbol__parent_filter(const struct symbol *parent) 111static 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
534int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, 577int 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
646int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists, 690int 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
657static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, 701static 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
824void hists__filter_by_dso(struct hists *self, const struct dso *dso) 867void 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);