aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2016-02-11 15:14:13 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-02-12 10:52:25 -0500
commit89fee70943232d73e3cc328634e0da253b6de9b5 (patch)
treec3e1028b2e6108e78201a7fdf70cc503cf89fe36
parent37d9bb580aa73c171c51fb93edf67a902bcb186f (diff)
perf hists: Do column alignment on the format iterator
We were doing column alignment in the format function for each cell, returning a string padded with spaces so that when the next column is printed the cursor is at its column alignment. This ends up needlessly printing trailing spaces, do it at the format iterator, that is where we know if it is needed, i.e. if there is more columns to be printed. This eliminates the need for triming lines when doing a dump using 'P' in the TUI browser and also produces far saner results with things like piping 'perf report' to 'less'. Right now only the formatters for sym->name and the 'locked' column (perf mem report), that are the ones that end up at the end of lines in the default 'perf report', 'perf top' and 'perf mem report' tools, the others will be done in a subsequent patch. In the end the 'width' parameter for the formatters now mean, in 'printf' terms, the 'precision', where before it was the field 'width'. Reported-by: Dave Jones <davej@codemonkey.org.uk> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/n/tip-s7iwl2gj23w92l6tibnrcqzr@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/ui/browsers/hists.c27
-rw-r--r--tools/perf/ui/stdio/hist.c1
-rw-r--r--tools/perf/util/hist.c21
-rw-r--r--tools/perf/util/hist.h5
-rw-r--r--tools/perf/util/sort.c13
5 files changed, 48 insertions, 19 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a5a5390476ac..1819771243f9 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1061,7 +1061,6 @@ static int hist_browser__show_entry(struct hist_browser *browser,
1061 struct hist_entry *entry, 1061 struct hist_entry *entry,
1062 unsigned short row) 1062 unsigned short row)
1063{ 1063{
1064 char s[256];
1065 int printed = 0; 1064 int printed = 0;
1066 int width = browser->b.width; 1065 int width = browser->b.width;
1067 char folded_sign = ' '; 1066 char folded_sign = ' ';
@@ -1086,16 +1085,18 @@ static int hist_browser__show_entry(struct hist_browser *browser,
1086 .folded_sign = folded_sign, 1085 .folded_sign = folded_sign,
1087 .current_entry = current_entry, 1086 .current_entry = current_entry,
1088 }; 1087 };
1089 struct perf_hpp hpp = {
1090 .buf = s,
1091 .size = sizeof(s),
1092 .ptr = &arg,
1093 };
1094 int column = 0; 1088 int column = 0;
1095 1089
1096 hist_browser__gotorc(browser, row, 0); 1090 hist_browser__gotorc(browser, row, 0);
1097 1091
1098 hists__for_each_format(browser->hists, fmt) { 1092 hists__for_each_format(browser->hists, fmt) {
1093 char s[2048];
1094 struct perf_hpp hpp = {
1095 .buf = s,
1096 .size = sizeof(s),
1097 .ptr = &arg,
1098 };
1099
1099 if (perf_hpp__should_skip(fmt, entry->hists) || 1100 if (perf_hpp__should_skip(fmt, entry->hists) ||
1100 column++ < browser->b.horiz_scroll) 1101 column++ < browser->b.horiz_scroll)
1101 continue; 1102 continue;
@@ -1120,11 +1121,18 @@ static int hist_browser__show_entry(struct hist_browser *browser,
1120 } 1121 }
1121 1122
1122 if (fmt->color) { 1123 if (fmt->color) {
1123 width -= fmt->color(fmt, &hpp, entry); 1124 int ret = fmt->color(fmt, &hpp, entry);
1125 hist_entry__snprintf_alignment(entry, &hpp, fmt, ret);
1126 /*
1127 * fmt->color() already used ui_browser to
1128 * print the non alignment bits, skip it (+ret):
1129 */
1130 ui_browser__printf(&browser->b, "%s", s + ret);
1124 } else { 1131 } else {
1125 width -= fmt->entry(fmt, &hpp, entry); 1132 hist_entry__snprintf_alignment(entry, &hpp, fmt, fmt->entry(fmt, &hpp, entry));
1126 ui_browser__printf(&browser->b, "%s", s); 1133 ui_browser__printf(&browser->b, "%s", s);
1127 } 1134 }
1135 width -= hpp.buf - s;
1128 } 1136 }
1129 1137
1130 /* The scroll bar isn't being used */ 1138 /* The scroll bar isn't being used */
@@ -1452,9 +1460,10 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
1452 first = false; 1460 first = false;
1453 1461
1454 ret = fmt->entry(fmt, &hpp, he); 1462 ret = fmt->entry(fmt, &hpp, he);
1463 ret = hist_entry__snprintf_alignment(he, &hpp, fmt, ret);
1455 advance_hpp(&hpp, ret); 1464 advance_hpp(&hpp, ret);
1456 } 1465 }
1457 printed += fprintf(fp, "%s\n", rtrim(s)); 1466 printed += fprintf(fp, "%s\n", s);
1458 1467
1459 if (folded_sign == '-') 1468 if (folded_sign == '-')
1460 printed += hist_browser__fprintf_callchain(browser, he, fp); 1469 printed += hist_browser__fprintf_callchain(browser, he, fp);
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 1a6e8f7f38c4..87b022ff03d8 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -403,6 +403,7 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
403 else 403 else
404 ret = fmt->entry(fmt, hpp, he); 404 ret = fmt->entry(fmt, hpp, he);
405 405
406 ret = hist_entry__snprintf_alignment(he, hpp, fmt, ret);
406 advance_hpp(hpp, ret); 407 advance_hpp(hpp, ret);
407 } 408 }
408 409
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 12f2d794dc28..561e9473a915 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1015,6 +1015,27 @@ void hist_entry__delete(struct hist_entry *he)
1015} 1015}
1016 1016
1017/* 1017/*
1018 * If this is not the last column, then we need to pad it according to the
1019 * pre-calculated max lenght for this column, otherwise don't bother adding
1020 * spaces because that would break viewing this with, for instance, 'less',
1021 * that would show tons of trailing spaces when a long C++ demangled method
1022 * names is sampled.
1023*/
1024int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp,
1025 struct perf_hpp_fmt *fmt, int printed)
1026{
1027 if (!list_is_last(&fmt->list, &he->hists->hpp_list->fields)) {
1028 const int width = fmt->width(fmt, hpp, hists_to_evsel(he->hists));
1029 if (printed < width) {
1030 advance_hpp(hpp, printed);
1031 printed = scnprintf(hpp->buf, hpp->size, "%-*s", width - printed, " ");
1032 }
1033 }
1034
1035 return printed;
1036}
1037
1038/*
1018 * collapse the histogram 1039 * collapse the histogram
1019 */ 1040 */
1020 1041
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 1c7544a8fe1a..840b6d6aa44f 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -122,11 +122,16 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
122int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, 122int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
123 int max_stack_depth, void *arg); 123 int max_stack_depth, void *arg);
124 124
125struct perf_hpp;
126struct perf_hpp_fmt;
127
125int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right); 128int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
126int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right); 129int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
127int hist_entry__transaction_len(void); 130int hist_entry__transaction_len(void);
128int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size, 131int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size,
129 struct hists *hists); 132 struct hists *hists);
133int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp,
134 struct perf_hpp_fmt *fmt, int printed);
130void hist_entry__delete(struct hist_entry *he); 135void hist_entry__delete(struct hist_entry *he);
131 136
132void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog); 137void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 8b54ede7ec1f..de715756f281 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -255,10 +255,8 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
255 ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name); 255 ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
256 ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", 256 ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
257 ip - map->unmap_ip(map, sym->start)); 257 ip - map->unmap_ip(map, sym->start));
258 ret += repsep_snprintf(bf + ret, size - ret, "%-*s",
259 width - ret, "");
260 } else { 258 } else {
261 ret += repsep_snprintf(bf + ret, size - ret, "%-*s", 259 ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
262 width - ret, 260 width - ret,
263 sym->name); 261 sym->name);
264 } 262 }
@@ -266,14 +264,9 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
266 size_t len = BITS_PER_LONG / 4; 264 size_t len = BITS_PER_LONG / 4;
267 ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", 265 ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx",
268 len, ip); 266 len, ip);
269 ret += repsep_snprintf(bf + ret, size - ret, "%-*s",
270 width - ret, "");
271 } 267 }
272 268
273 if (ret > width) 269 return ret;
274 bf[width] = '\0';
275
276 return width;
277} 270}
278 271
279static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, 272static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
@@ -819,7 +812,7 @@ static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
819 else 812 else
820 out = "No"; 813 out = "No";
821 814
822 return repsep_snprintf(bf, size, "%-*s", width, out); 815 return repsep_snprintf(bf, size, "%.*s", width, out);
823} 816}
824 817
825static int64_t 818static int64_t