diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-03-18 04:23:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-03-18 04:23:09 -0400 |
commit | 0afd2d51029961281572d02545c7bde1b3f4292c (patch) | |
tree | 73f8b07ee0b43ebd93fb0556b0af0f217f897d5c /tools/perf/ui | |
parent | 81827ed8d85e892311965dc9ec4120b2b2e745bd (diff) | |
parent | d75e6097ef1f7669deb500fbbdf53cfe524f1b53 (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo:
User visible:
* Add several futex 'perf bench' microbenchmarks (Davidlohr Bueso)
* Speed up thread map generation (Don Zickus)
* Fix synthesizing mmaps for threads (Don Zickus)
* Fix invalid output on event group stdio report (Namhyung Kim)
* Introduce 'perf kvm --list-cmds' command line option for use by
scripts (Ramkumar Ramachandra)
Documentation:
* Clarify load-latency information in the 'perf mem' docs (Andi Kleen)
* Clarify x86 register naming in 'perf probe' docs (Andi Kleen)
Refactorings:
* hists browser refactorings to reuse code accross UIs (Namhyung Kim)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/ui')
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 122 | ||||
-rw-r--r-- | tools/perf/ui/gtk/hists.c | 78 | ||||
-rw-r--r-- | tools/perf/ui/hist.c | 138 | ||||
-rw-r--r-- | tools/perf/ui/stdio/hist.c | 11 |
4 files changed, 155 insertions, 194 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b720b92eba6e..7ec871af3f6f 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -587,95 +587,52 @@ struct hpp_arg { | |||
587 | bool current_entry; | 587 | bool current_entry; |
588 | }; | 588 | }; |
589 | 589 | ||
590 | static int __hpp__color_callchain(struct hpp_arg *arg) | 590 | static int __hpp__overhead_callback(struct perf_hpp *hpp, bool front) |
591 | { | 591 | { |
592 | if (!symbol_conf.use_callchain) | ||
593 | return 0; | ||
594 | |||
595 | slsmg_printf("%c ", arg->folded_sign); | ||
596 | return 2; | ||
597 | } | ||
598 | |||
599 | static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he, | ||
600 | u64 (*get_field)(struct hist_entry *), | ||
601 | int (*callchain_cb)(struct hpp_arg *)) | ||
602 | { | ||
603 | int ret = 0; | ||
604 | double percent = 0.0; | ||
605 | struct hists *hists = he->hists; | ||
606 | struct hpp_arg *arg = hpp->ptr; | 592 | struct hpp_arg *arg = hpp->ptr; |
607 | 593 | ||
608 | if (hists->stats.total_period) | 594 | if (arg->current_entry && arg->b->navkeypressed) |
609 | percent = 100.0 * get_field(he) / hists->stats.total_period; | 595 | ui_browser__set_color(arg->b, HE_COLORSET_SELECTED); |
610 | 596 | else | |
611 | ui_browser__set_percent_color(arg->b, percent, arg->current_entry); | 597 | ui_browser__set_color(arg->b, HE_COLORSET_NORMAL); |
612 | |||
613 | if (callchain_cb) | ||
614 | ret += callchain_cb(arg); | ||
615 | |||
616 | ret += scnprintf(hpp->buf, hpp->size, "%6.2f%%", percent); | ||
617 | slsmg_printf("%s", hpp->buf); | ||
618 | |||
619 | if (symbol_conf.event_group) { | ||
620 | int prev_idx, idx_delta; | ||
621 | struct perf_evsel *evsel = hists_to_evsel(hists); | ||
622 | struct hist_entry *pair; | ||
623 | int nr_members = evsel->nr_members; | ||
624 | |||
625 | if (nr_members <= 1) | ||
626 | goto out; | ||
627 | 598 | ||
628 | prev_idx = perf_evsel__group_idx(evsel); | 599 | if (front) { |
600 | if (!symbol_conf.use_callchain) | ||
601 | return 0; | ||
629 | 602 | ||
630 | list_for_each_entry(pair, &he->pairs.head, pairs.node) { | 603 | slsmg_printf("%c ", arg->folded_sign); |
631 | u64 period = get_field(pair); | 604 | return 2; |
632 | u64 total = pair->hists->stats.total_period; | 605 | } |
633 | 606 | ||
634 | if (!total) | 607 | return 0; |
635 | continue; | 608 | } |
636 | 609 | ||
637 | evsel = hists_to_evsel(pair->hists); | 610 | static int __hpp__color_callback(struct perf_hpp *hpp, bool front __maybe_unused) |
638 | idx_delta = perf_evsel__group_idx(evsel) - prev_idx - 1; | 611 | { |
612 | struct hpp_arg *arg = hpp->ptr; | ||
639 | 613 | ||
640 | while (idx_delta--) { | 614 | if (!arg->current_entry || !arg->b->navkeypressed) |
641 | /* | 615 | ui_browser__set_color(arg->b, HE_COLORSET_NORMAL); |
642 | * zero-fill group members in the middle which | 616 | return 0; |
643 | * have no sample | 617 | } |
644 | */ | ||
645 | ui_browser__set_percent_color(arg->b, 0.0, | ||
646 | arg->current_entry); | ||
647 | ret += scnprintf(hpp->buf, hpp->size, | ||
648 | " %6.2f%%", 0.0); | ||
649 | slsmg_printf("%s", hpp->buf); | ||
650 | } | ||
651 | 618 | ||
652 | percent = 100.0 * period / total; | 619 | static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) |
653 | ui_browser__set_percent_color(arg->b, percent, | 620 | { |
654 | arg->current_entry); | 621 | struct hpp_arg *arg = hpp->ptr; |
655 | ret += scnprintf(hpp->buf, hpp->size, | 622 | int ret; |
656 | " %6.2f%%", percent); | 623 | va_list args; |
657 | slsmg_printf("%s", hpp->buf); | 624 | double percent; |
658 | 625 | ||
659 | prev_idx = perf_evsel__group_idx(evsel); | 626 | va_start(args, fmt); |
660 | } | 627 | percent = va_arg(args, double); |
628 | va_end(args); | ||
661 | 629 | ||
662 | idx_delta = nr_members - prev_idx - 1; | 630 | ui_browser__set_percent_color(arg->b, percent, arg->current_entry); |
663 | 631 | ||
664 | while (idx_delta--) { | 632 | ret = scnprintf(hpp->buf, hpp->size, fmt, percent); |
665 | /* | 633 | slsmg_printf("%s", hpp->buf); |
666 | * zero-fill group members at last which have no sample | ||
667 | */ | ||
668 | ui_browser__set_percent_color(arg->b, 0.0, | ||
669 | arg->current_entry); | ||
670 | ret += scnprintf(hpp->buf, hpp->size, | ||
671 | " %6.2f%%", 0.0); | ||
672 | slsmg_printf("%s", hpp->buf); | ||
673 | } | ||
674 | } | ||
675 | out: | ||
676 | if (!arg->current_entry || !arg->b->navkeypressed) | ||
677 | ui_browser__set_color(arg->b, HE_COLORSET_NORMAL); | ||
678 | 634 | ||
635 | advance_hpp(hpp, ret); | ||
679 | return ret; | 636 | return ret; |
680 | } | 637 | } |
681 | 638 | ||
@@ -690,14 +647,15 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\ | |||
690 | struct perf_hpp *hpp, \ | 647 | struct perf_hpp *hpp, \ |
691 | struct hist_entry *he) \ | 648 | struct hist_entry *he) \ |
692 | { \ | 649 | { \ |
693 | return __hpp__color_fmt(hpp, he, __hpp_get_##_field, _cb); \ | 650 | return __hpp__fmt(hpp, he, __hpp_get_##_field, _cb, " %6.2f%%", \ |
651 | __hpp__slsmg_color_printf, true); \ | ||
694 | } | 652 | } |
695 | 653 | ||
696 | __HPP_COLOR_PERCENT_FN(overhead, period, __hpp__color_callchain) | 654 | __HPP_COLOR_PERCENT_FN(overhead, period, __hpp__overhead_callback) |
697 | __HPP_COLOR_PERCENT_FN(overhead_sys, period_sys, NULL) | 655 | __HPP_COLOR_PERCENT_FN(overhead_sys, period_sys, __hpp__color_callback) |
698 | __HPP_COLOR_PERCENT_FN(overhead_us, period_us, NULL) | 656 | __HPP_COLOR_PERCENT_FN(overhead_us, period_us, __hpp__color_callback) |
699 | __HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys, NULL) | 657 | __HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys, __hpp__color_callback) |
700 | __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us, NULL) | 658 | __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us, __hpp__color_callback) |
701 | 659 | ||
702 | #undef __HPP_COLOR_PERCENT_FN | 660 | #undef __HPP_COLOR_PERCENT_FN |
703 | 661 | ||
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 5b95c44f3435..e395ef9b0ae0 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c | |||
@@ -8,16 +8,24 @@ | |||
8 | 8 | ||
9 | #define MAX_COLUMNS 32 | 9 | #define MAX_COLUMNS 32 |
10 | 10 | ||
11 | static int __percent_color_snprintf(char *buf, size_t size, double percent) | 11 | static int __percent_color_snprintf(struct perf_hpp *hpp, const char *fmt, ...) |
12 | { | 12 | { |
13 | int ret = 0; | 13 | int ret = 0; |
14 | va_list args; | ||
15 | double percent; | ||
14 | const char *markup; | 16 | const char *markup; |
17 | char *buf = hpp->buf; | ||
18 | size_t size = hpp->size; | ||
19 | |||
20 | va_start(args, fmt); | ||
21 | percent = va_arg(args, double); | ||
22 | va_end(args); | ||
15 | 23 | ||
16 | markup = perf_gtk__get_percent_color(percent); | 24 | markup = perf_gtk__get_percent_color(percent); |
17 | if (markup) | 25 | if (markup) |
18 | ret += scnprintf(buf, size, markup); | 26 | ret += scnprintf(buf, size, markup); |
19 | 27 | ||
20 | ret += scnprintf(buf + ret, size - ret, " %6.2f%%", percent); | 28 | ret += scnprintf(buf + ret, size - ret, fmt, percent); |
21 | 29 | ||
22 | if (markup) | 30 | if (markup) |
23 | ret += scnprintf(buf + ret, size - ret, "</span>"); | 31 | ret += scnprintf(buf + ret, size - ret, "</span>"); |
@@ -25,66 +33,6 @@ static int __percent_color_snprintf(char *buf, size_t size, double percent) | |||
25 | return ret; | 33 | return ret; |
26 | } | 34 | } |
27 | 35 | ||
28 | |||
29 | static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he, | ||
30 | u64 (*get_field)(struct hist_entry *)) | ||
31 | { | ||
32 | int ret; | ||
33 | double percent = 0.0; | ||
34 | struct hists *hists = he->hists; | ||
35 | struct perf_evsel *evsel = hists_to_evsel(hists); | ||
36 | |||
37 | if (hists->stats.total_period) | ||
38 | percent = 100.0 * get_field(he) / hists->stats.total_period; | ||
39 | |||
40 | ret = __percent_color_snprintf(hpp->buf, hpp->size, percent); | ||
41 | |||
42 | if (perf_evsel__is_group_event(evsel)) { | ||
43 | int prev_idx, idx_delta; | ||
44 | struct hist_entry *pair; | ||
45 | int nr_members = evsel->nr_members; | ||
46 | |||
47 | prev_idx = perf_evsel__group_idx(evsel); | ||
48 | |||
49 | list_for_each_entry(pair, &he->pairs.head, pairs.node) { | ||
50 | u64 period = get_field(pair); | ||
51 | u64 total = pair->hists->stats.total_period; | ||
52 | |||
53 | evsel = hists_to_evsel(pair->hists); | ||
54 | idx_delta = perf_evsel__group_idx(evsel) - prev_idx - 1; | ||
55 | |||
56 | while (idx_delta--) { | ||
57 | /* | ||
58 | * zero-fill group members in the middle which | ||
59 | * have no sample | ||
60 | */ | ||
61 | ret += __percent_color_snprintf(hpp->buf + ret, | ||
62 | hpp->size - ret, | ||
63 | 0.0); | ||
64 | } | ||
65 | |||
66 | percent = 100.0 * period / total; | ||
67 | ret += __percent_color_snprintf(hpp->buf + ret, | ||
68 | hpp->size - ret, | ||
69 | percent); | ||
70 | |||
71 | prev_idx = perf_evsel__group_idx(evsel); | ||
72 | } | ||
73 | |||
74 | idx_delta = nr_members - prev_idx - 1; | ||
75 | |||
76 | while (idx_delta--) { | ||
77 | /* | ||
78 | * zero-fill group members at last which have no sample | ||
79 | */ | ||
80 | ret += __percent_color_snprintf(hpp->buf + ret, | ||
81 | hpp->size - ret, | ||
82 | 0.0); | ||
83 | } | ||
84 | } | ||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | #define __HPP_COLOR_PERCENT_FN(_type, _field) \ | 36 | #define __HPP_COLOR_PERCENT_FN(_type, _field) \ |
89 | static u64 he_get_##_field(struct hist_entry *he) \ | 37 | static u64 he_get_##_field(struct hist_entry *he) \ |
90 | { \ | 38 | { \ |
@@ -95,7 +43,8 @@ static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, | |||
95 | struct perf_hpp *hpp, \ | 43 | struct perf_hpp *hpp, \ |
96 | struct hist_entry *he) \ | 44 | struct hist_entry *he) \ |
97 | { \ | 45 | { \ |
98 | return __hpp__color_fmt(hpp, he, he_get_##_field); \ | 46 | return __hpp__fmt(hpp, he, he_get_##_field, NULL, " %6.2f%%", \ |
47 | __percent_color_snprintf, true); \ | ||
99 | } | 48 | } |
100 | 49 | ||
101 | __HPP_COLOR_PERCENT_FN(overhead, period) | 50 | __HPP_COLOR_PERCENT_FN(overhead, period) |
@@ -216,7 +165,6 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, | |||
216 | struct perf_hpp hpp = { | 165 | struct perf_hpp hpp = { |
217 | .buf = s, | 166 | .buf = s, |
218 | .size = sizeof(s), | 167 | .size = sizeof(s), |
219 | .ptr = hists_to_evsel(hists), | ||
220 | }; | 168 | }; |
221 | 169 | ||
222 | nr_cols = 0; | 170 | nr_cols = 0; |
@@ -243,7 +191,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, | |||
243 | col_idx = 0; | 191 | col_idx = 0; |
244 | 192 | ||
245 | perf_hpp__for_each_format(fmt) { | 193 | perf_hpp__for_each_format(fmt) { |
246 | fmt->header(fmt, &hpp); | 194 | fmt->header(fmt, &hpp, hists_to_evsel(hists)); |
247 | 195 | ||
248 | gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), | 196 | gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), |
249 | -1, ltrim(s), | 197 | -1, ltrim(s), |
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 78f4c92e9b73..0f403b83e9d1 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c | |||
@@ -8,16 +8,27 @@ | |||
8 | 8 | ||
9 | /* hist period print (hpp) functions */ | 9 | /* hist period print (hpp) functions */ |
10 | 10 | ||
11 | typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...); | 11 | #define hpp__call_print_fn(hpp, fn, fmt, ...) \ |
12 | 12 | ({ \ | |
13 | static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, | 13 | int __ret = fn(hpp, fmt, ##__VA_ARGS__); \ |
14 | u64 (*get_field)(struct hist_entry *), | 14 | advance_hpp(hpp, __ret); \ |
15 | const char *fmt, hpp_snprint_fn print_fn, | 15 | __ret; \ |
16 | bool fmt_percent) | 16 | }) |
17 | |||
18 | int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, | ||
19 | hpp_field_fn get_field, hpp_callback_fn callback, | ||
20 | const char *fmt, hpp_snprint_fn print_fn, bool fmt_percent) | ||
17 | { | 21 | { |
18 | int ret; | 22 | int ret = 0; |
19 | struct hists *hists = he->hists; | 23 | struct hists *hists = he->hists; |
20 | struct perf_evsel *evsel = hists_to_evsel(hists); | 24 | struct perf_evsel *evsel = hists_to_evsel(hists); |
25 | char *buf = hpp->buf; | ||
26 | size_t size = hpp->size; | ||
27 | |||
28 | if (callback) { | ||
29 | ret = callback(hpp, true); | ||
30 | advance_hpp(hpp, ret); | ||
31 | } | ||
21 | 32 | ||
22 | if (fmt_percent) { | 33 | if (fmt_percent) { |
23 | double percent = 0.0; | 34 | double percent = 0.0; |
@@ -26,9 +37,9 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, | |||
26 | percent = 100.0 * get_field(he) / | 37 | percent = 100.0 * get_field(he) / |
27 | hists->stats.total_period; | 38 | hists->stats.total_period; |
28 | 39 | ||
29 | ret = print_fn(hpp->buf, hpp->size, fmt, percent); | 40 | ret += hpp__call_print_fn(hpp, print_fn, fmt, percent); |
30 | } else | 41 | } else |
31 | ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he)); | 42 | ret += hpp__call_print_fn(hpp, print_fn, fmt, get_field(he)); |
32 | 43 | ||
33 | if (perf_evsel__is_group_event(evsel)) { | 44 | if (perf_evsel__is_group_event(evsel)) { |
34 | int prev_idx, idx_delta; | 45 | int prev_idx, idx_delta; |
@@ -52,16 +63,22 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, | |||
52 | * zero-fill group members in the middle which | 63 | * zero-fill group members in the middle which |
53 | * have no sample | 64 | * have no sample |
54 | */ | 65 | */ |
55 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | 66 | if (fmt_percent) { |
56 | fmt, 0); | 67 | ret += hpp__call_print_fn(hpp, print_fn, |
68 | fmt, 0.0); | ||
69 | } else { | ||
70 | ret += hpp__call_print_fn(hpp, print_fn, | ||
71 | fmt, 0ULL); | ||
72 | } | ||
57 | } | 73 | } |
58 | 74 | ||
59 | if (fmt_percent) | 75 | if (fmt_percent) { |
60 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | 76 | ret += hpp__call_print_fn(hpp, print_fn, fmt, |
61 | fmt, 100.0 * period / total); | 77 | 100.0 * period / total); |
62 | else | 78 | } else { |
63 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | 79 | ret += hpp__call_print_fn(hpp, print_fn, fmt, |
64 | fmt, period); | 80 | period); |
81 | } | ||
65 | 82 | ||
66 | prev_idx = perf_evsel__group_idx(evsel); | 83 | prev_idx = perf_evsel__group_idx(evsel); |
67 | } | 84 | } |
@@ -72,41 +89,87 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, | |||
72 | /* | 89 | /* |
73 | * zero-fill group members at last which have no sample | 90 | * zero-fill group members at last which have no sample |
74 | */ | 91 | */ |
75 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | 92 | if (fmt_percent) { |
76 | fmt, 0); | 93 | ret += hpp__call_print_fn(hpp, print_fn, |
94 | fmt, 0.0); | ||
95 | } else { | ||
96 | ret += hpp__call_print_fn(hpp, print_fn, | ||
97 | fmt, 0ULL); | ||
98 | } | ||
77 | } | 99 | } |
78 | } | 100 | } |
101 | |||
102 | if (callback) { | ||
103 | int __ret = callback(hpp, false); | ||
104 | |||
105 | advance_hpp(hpp, __ret); | ||
106 | ret += __ret; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Restore original buf and size as it's where caller expects | ||
111 | * the result will be saved. | ||
112 | */ | ||
113 | hpp->buf = buf; | ||
114 | hpp->size = size; | ||
115 | |||
79 | return ret; | 116 | return ret; |
80 | } | 117 | } |
81 | 118 | ||
82 | #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ | 119 | #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ |
83 | static int hpp__header_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ | 120 | static int hpp__header_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ |
84 | struct perf_hpp *hpp) \ | 121 | struct perf_hpp *hpp, \ |
122 | struct perf_evsel *evsel) \ | ||
85 | { \ | 123 | { \ |
86 | int len = _min_width; \ | 124 | int len = _min_width; \ |
87 | \ | 125 | \ |
88 | if (symbol_conf.event_group) { \ | 126 | if (symbol_conf.event_group) \ |
89 | struct perf_evsel *evsel = hpp->ptr; \ | ||
90 | \ | ||
91 | len = max(len, evsel->nr_members * _unit_width); \ | 127 | len = max(len, evsel->nr_members * _unit_width); \ |
92 | } \ | 128 | \ |
93 | return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ | 129 | return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ |
94 | } | 130 | } |
95 | 131 | ||
96 | #define __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ | 132 | #define __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ |
97 | static int hpp__width_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ | 133 | static int hpp__width_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ |
98 | struct perf_hpp *hpp __maybe_unused) \ | 134 | struct perf_hpp *hpp __maybe_unused, \ |
135 | struct perf_evsel *evsel) \ | ||
99 | { \ | 136 | { \ |
100 | int len = _min_width; \ | 137 | int len = _min_width; \ |
101 | \ | 138 | \ |
102 | if (symbol_conf.event_group) { \ | 139 | if (symbol_conf.event_group) \ |
103 | struct perf_evsel *evsel = hpp->ptr; \ | ||
104 | \ | ||
105 | len = max(len, evsel->nr_members * _unit_width); \ | 140 | len = max(len, evsel->nr_members * _unit_width); \ |
106 | } \ | 141 | \ |
107 | return len; \ | 142 | return len; \ |
108 | } | 143 | } |
109 | 144 | ||
145 | static int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...) | ||
146 | { | ||
147 | va_list args; | ||
148 | ssize_t ssize = hpp->size; | ||
149 | double percent; | ||
150 | int ret; | ||
151 | |||
152 | va_start(args, fmt); | ||
153 | percent = va_arg(args, double); | ||
154 | ret = value_color_snprintf(hpp->buf, hpp->size, fmt, percent); | ||
155 | va_end(args); | ||
156 | |||
157 | return (ret >= ssize) ? (ssize - 1) : ret; | ||
158 | } | ||
159 | |||
160 | static int hpp_entry_scnprintf(struct perf_hpp *hpp, const char *fmt, ...) | ||
161 | { | ||
162 | va_list args; | ||
163 | ssize_t ssize = hpp->size; | ||
164 | int ret; | ||
165 | |||
166 | va_start(args, fmt); | ||
167 | ret = vsnprintf(hpp->buf, hpp->size, fmt, args); | ||
168 | va_end(args); | ||
169 | |||
170 | return (ret >= ssize) ? (ssize - 1) : ret; | ||
171 | } | ||
172 | |||
110 | #define __HPP_COLOR_PERCENT_FN(_type, _field) \ | 173 | #define __HPP_COLOR_PERCENT_FN(_type, _field) \ |
111 | static u64 he_get_##_field(struct hist_entry *he) \ | 174 | static u64 he_get_##_field(struct hist_entry *he) \ |
112 | { \ | 175 | { \ |
@@ -116,8 +179,8 @@ static u64 he_get_##_field(struct hist_entry *he) \ | |||
116 | static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ | 179 | static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ |
117 | struct perf_hpp *hpp, struct hist_entry *he) \ | 180 | struct perf_hpp *hpp, struct hist_entry *he) \ |
118 | { \ | 181 | { \ |
119 | return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \ | 182 | return __hpp__fmt(hpp, he, he_get_##_field, NULL, " %6.2f%%", \ |
120 | percent_color_snprintf, true); \ | 183 | hpp_color_scnprintf, true); \ |
121 | } | 184 | } |
122 | 185 | ||
123 | #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ | 186 | #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ |
@@ -125,8 +188,8 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ | |||
125 | struct perf_hpp *hpp, struct hist_entry *he) \ | 188 | struct perf_hpp *hpp, struct hist_entry *he) \ |
126 | { \ | 189 | { \ |
127 | const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ | 190 | const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ |
128 | return __hpp__fmt(hpp, he, he_get_##_field, fmt, \ | 191 | return __hpp__fmt(hpp, he, he_get_##_field, NULL, fmt, \ |
129 | scnprintf, true); \ | 192 | hpp_entry_scnprintf, true); \ |
130 | } | 193 | } |
131 | 194 | ||
132 | #define __HPP_ENTRY_RAW_FN(_type, _field) \ | 195 | #define __HPP_ENTRY_RAW_FN(_type, _field) \ |
@@ -139,7 +202,8 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ | |||
139 | struct perf_hpp *hpp, struct hist_entry *he) \ | 202 | struct perf_hpp *hpp, struct hist_entry *he) \ |
140 | { \ | 203 | { \ |
141 | const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ | 204 | const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ |
142 | return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf, false); \ | 205 | return __hpp__fmt(hpp, he, he_get_raw_##_field, NULL, fmt, \ |
206 | hpp_entry_scnprintf, false); \ | ||
143 | } | 207 | } |
144 | 208 | ||
145 | #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ | 209 | #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ |
@@ -263,15 +327,13 @@ unsigned int hists__sort_list_width(struct hists *hists) | |||
263 | struct perf_hpp_fmt *fmt; | 327 | struct perf_hpp_fmt *fmt; |
264 | struct sort_entry *se; | 328 | struct sort_entry *se; |
265 | int i = 0, ret = 0; | 329 | int i = 0, ret = 0; |
266 | struct perf_hpp dummy_hpp = { | 330 | struct perf_hpp dummy_hpp; |
267 | .ptr = hists_to_evsel(hists), | ||
268 | }; | ||
269 | 331 | ||
270 | perf_hpp__for_each_format(fmt) { | 332 | perf_hpp__for_each_format(fmt) { |
271 | if (i) | 333 | if (i) |
272 | ret += 2; | 334 | ret += 2; |
273 | 335 | ||
274 | ret += fmt->width(fmt, &dummy_hpp); | 336 | ret += fmt->width(fmt, &dummy_hpp, hists_to_evsel(hists)); |
275 | } | 337 | } |
276 | 338 | ||
277 | list_for_each_entry(se, &hist_entry__sort_list, list) | 339 | list_for_each_entry(se, &hist_entry__sort_list, list) |
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 831fbb77d1ff..d59893edf031 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -306,12 +306,6 @@ static size_t hist_entry__callchain_fprintf(struct hist_entry *he, | |||
306 | return hist_entry_callchain__fprintf(he, total_period, left_margin, fp); | 306 | return hist_entry_callchain__fprintf(he, total_period, left_margin, fp); |
307 | } | 307 | } |
308 | 308 | ||
309 | static inline void advance_hpp(struct perf_hpp *hpp, int inc) | ||
310 | { | ||
311 | hpp->buf += inc; | ||
312 | hpp->size -= inc; | ||
313 | } | ||
314 | |||
315 | static int hist_entry__period_snprintf(struct perf_hpp *hpp, | 309 | static int hist_entry__period_snprintf(struct perf_hpp *hpp, |
316 | struct hist_entry *he) | 310 | struct hist_entry *he) |
317 | { | 311 | { |
@@ -385,7 +379,6 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
385 | struct perf_hpp dummy_hpp = { | 379 | struct perf_hpp dummy_hpp = { |
386 | .buf = bf, | 380 | .buf = bf, |
387 | .size = sizeof(bf), | 381 | .size = sizeof(bf), |
388 | .ptr = hists_to_evsel(hists), | ||
389 | }; | 382 | }; |
390 | bool first = true; | 383 | bool first = true; |
391 | size_t linesz; | 384 | size_t linesz; |
@@ -404,7 +397,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
404 | else | 397 | else |
405 | first = false; | 398 | first = false; |
406 | 399 | ||
407 | fmt->header(fmt, &dummy_hpp); | 400 | fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); |
408 | fprintf(fp, "%s", bf); | 401 | fprintf(fp, "%s", bf); |
409 | } | 402 | } |
410 | 403 | ||
@@ -449,7 +442,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
449 | else | 442 | else |
450 | first = false; | 443 | first = false; |
451 | 444 | ||
452 | width = fmt->width(fmt, &dummy_hpp); | 445 | width = fmt->width(fmt, &dummy_hpp, hists_to_evsel(hists)); |
453 | for (i = 0; i < width; i++) | 446 | for (i = 0; i < width; i++) |
454 | fprintf(fp, "."); | 447 | fprintf(fp, "."); |
455 | } | 448 | } |