aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-09-09 04:39:14 -0400
committerIngo Molnar <mingo@kernel.org>2012-09-09 04:39:14 -0400
commitd5cb2aef4fda355fbafe8db4f425b73ea94d2019 (patch)
treef6812e5248557bd16803f787e0cbc9d57ab60133
parentef34eb4da3eb62a1511592adf7c76d74faca0b14 (diff)
parent6c7f631261064762a8ba1ee34fc2b76d117ef3fa (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 Carvalho de Melo: * Don't pass const char pointers to basename, so that we can unconditionally use libgen.h and thus avoid ifdef BIONIC lines, from David Ahern * Fix assert/BUG_ON when NDEBUG is defined, from Irina Tirdea. * Refactor hist formatting so that it can be reused with the GTK browser, From Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/bench/sched-pipe.c6
-rw-r--r--tools/perf/builtin-diff.c1
-rw-r--r--tools/perf/ui/browsers/hists.c96
-rw-r--r--tools/perf/ui/gtk/browser.c101
-rw-r--r--tools/perf/ui/gtk/gtk.h1
-rw-r--r--tools/perf/ui/gtk/setup.c1
-rw-r--r--tools/perf/ui/hist.c389
-rw-r--r--tools/perf/ui/setup.c8
-rw-r--r--tools/perf/ui/stdio/hist.c239
-rw-r--r--tools/perf/ui/tui/setup.c4
-rw-r--r--tools/perf/util/annotate.c9
-rw-r--r--tools/perf/util/hist.c33
-rw-r--r--tools/perf/util/hist.h37
-rw-r--r--tools/perf/util/include/linux/kernel.h4
-rw-r--r--tools/perf/util/probe-event.c12
-rw-r--r--tools/perf/util/symbol.h2
17 files changed, 665 insertions, 280 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 3eda4921573..e4b2e8f2606 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -403,7 +403,9 @@ LIB_OBJS += $(OUTPUT)util/cgroup.o
403LIB_OBJS += $(OUTPUT)util/target.o 403LIB_OBJS += $(OUTPUT)util/target.o
404LIB_OBJS += $(OUTPUT)util/rblist.o 404LIB_OBJS += $(OUTPUT)util/rblist.o
405LIB_OBJS += $(OUTPUT)util/intlist.o 405LIB_OBJS += $(OUTPUT)util/intlist.o
406
406LIB_OBJS += $(OUTPUT)ui/helpline.o 407LIB_OBJS += $(OUTPUT)ui/helpline.o
408LIB_OBJS += $(OUTPUT)ui/hist.o
407LIB_OBJS += $(OUTPUT)ui/stdio/hist.o 409LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
408 410
409BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o 411BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
index 0c7454f8b8a..15911e9c587 100644
--- a/tools/perf/bench/sched-pipe.c
+++ b/tools/perf/bench/sched-pipe.c
@@ -56,13 +56,13 @@ int bench_sched_pipe(int argc, const char **argv,
56 * causes error in building environment for perf 56 * causes error in building environment for perf
57 */ 57 */
58 int __used ret, wait_stat; 58 int __used ret, wait_stat;
59 pid_t pid, retpid; 59 pid_t pid, retpid __used;
60 60
61 argc = parse_options(argc, argv, options, 61 argc = parse_options(argc, argv, options,
62 bench_sched_pipe_usage, 0); 62 bench_sched_pipe_usage, 0);
63 63
64 assert(!pipe(pipe_1)); 64 BUG_ON(pipe(pipe_1));
65 assert(!pipe(pipe_2)); 65 BUG_ON(pipe(pipe_2));
66 66
67 pid = fork(); 67 pid = fork();
68 assert(pid >= 0); 68 assert(pid >= 0);
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index e9933fdd256..c4c6d76b70e 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -264,6 +264,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __used)
264 if (symbol__init() < 0) 264 if (symbol__init() < 0)
265 return -1; 265 return -1;
266 266
267 perf_hpp__init(true, show_displacement);
267 setup_sorting(diff_usage, options); 268 setup_sorting(diff_usage, options);
268 setup_pager(); 269 setup_pager();
269 270
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 81bd8c2af73..5a5739bbe6a 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -28,6 +28,8 @@ struct hist_browser {
28 bool has_symbols; 28 bool has_symbols;
29}; 29};
30 30
31extern void hist_browser__init_hpp(void);
32
31static int hists__browser_title(struct hists *hists, char *bf, size_t size, 33static int hists__browser_title(struct hists *hists, char *bf, size_t size,
32 const char *ev_name); 34 const char *ev_name);
33 35
@@ -563,14 +565,47 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
563 return row - first_row; 565 return row - first_row;
564} 566}
565 567
568#define HPP__COLOR_FN(_name, _field) \
569static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
570 struct hist_entry *he) \
571{ \
572 double percent = 100.0 * he->_field / hpp->total_period; \
573 *(double *)hpp->ptr = percent; \
574 return scnprintf(hpp->buf, hpp->size, "%5.2f%%", percent); \
575}
576
577HPP__COLOR_FN(overhead, period)
578HPP__COLOR_FN(overhead_sys, period_sys)
579HPP__COLOR_FN(overhead_us, period_us)
580HPP__COLOR_FN(overhead_guest_sys, period_guest_sys)
581HPP__COLOR_FN(overhead_guest_us, period_guest_us)
582
583#undef HPP__COLOR_FN
584
585void hist_browser__init_hpp(void)
586{
587 perf_hpp__init(false, false);
588
589 perf_hpp__format[PERF_HPP__OVERHEAD].color =
590 hist_browser__hpp_color_overhead;
591 perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color =
592 hist_browser__hpp_color_overhead_sys;
593 perf_hpp__format[PERF_HPP__OVERHEAD_US].color =
594 hist_browser__hpp_color_overhead_us;
595 perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_SYS].color =
596 hist_browser__hpp_color_overhead_guest_sys;
597 perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_US].color =
598 hist_browser__hpp_color_overhead_guest_us;
599}
600
566static int hist_browser__show_entry(struct hist_browser *browser, 601static int hist_browser__show_entry(struct hist_browser *browser,
567 struct hist_entry *entry, 602 struct hist_entry *entry,
568 unsigned short row) 603 unsigned short row)
569{ 604{
570 char s[256]; 605 char s[256];
571 double percent; 606 double percent;
572 int printed = 0; 607 int i, printed = 0;
573 int width = browser->b.width - 6; /* The percentage */ 608 int width = browser->b.width - 1;
574 char folded_sign = ' '; 609 char folded_sign = ' ';
575 bool current_entry = ui_browser__is_current_entry(&browser->b, row); 610 bool current_entry = ui_browser__is_current_entry(&browser->b, row);
576 off_t row_offset = entry->row_offset; 611 off_t row_offset = entry->row_offset;
@@ -586,35 +621,50 @@ static int hist_browser__show_entry(struct hist_browser *browser,
586 } 621 }
587 622
588 if (row_offset == 0) { 623 if (row_offset == 0) {
589 hist_entry__sort_snprintf(entry, s, sizeof(s), browser->hists); 624 struct perf_hpp hpp = {
590 percent = (entry->period * 100.0) / browser->hists->stats.total_period; 625 .buf = s,
626 .size = sizeof(s),
627 .total_period = browser->hists->stats.total_period,
628 };
591 629
592 ui_browser__set_percent_color(&browser->b, percent, current_entry); 630 ui_browser__gotorc(&browser->b, row, 1);
593 ui_browser__gotorc(&browser->b, row, 0);
594 if (symbol_conf.use_callchain) {
595 slsmg_printf("%c ", folded_sign);
596 width -= 2;
597 }
598 631
599 slsmg_printf(" %5.2f%%", percent); 632 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
633 if (!perf_hpp__format[i].cond)
634 continue;
600 635
601 /* The scroll bar isn't being used */ 636 if (i) {
602 if (!browser->b.navkeypressed) 637 slsmg_printf(" ");
603 width += 1; 638 width -= 2;
639 }
604 640
605 if (!current_entry || !browser->b.navkeypressed) 641 if (perf_hpp__format[i].color) {
606 ui_browser__set_color(&browser->b, HE_COLORSET_NORMAL); 642 hpp.ptr = &percent;
643 /* It will set percent for us. See HPP__COLOR_FN above. */
644 width -= perf_hpp__format[i].color(&hpp, entry);
607 645
608 if (symbol_conf.show_nr_samples) { 646 ui_browser__set_percent_color(&browser->b, percent, current_entry);
609 slsmg_printf(" %11u", entry->nr_events); 647
610 width -= 12; 648 if (i == 0 && symbol_conf.use_callchain) {
611 } 649 slsmg_printf("%c ", folded_sign);
650 width -= 2;
651 }
652
653 slsmg_printf("%s", s);
612 654
613 if (symbol_conf.show_total_period) { 655 if (!current_entry || !browser->b.navkeypressed)
614 slsmg_printf(" %12" PRIu64, entry->period); 656 ui_browser__set_color(&browser->b, HE_COLORSET_NORMAL);
615 width -= 13; 657 } else {
658 width -= perf_hpp__format[i].entry(&hpp, entry);
659 slsmg_printf("%s", s);
660 }
616 } 661 }
617 662
663 /* The scroll bar isn't being used */
664 if (!browser->b.navkeypressed)
665 width += 1;
666
667 hist_entry__sort_snprintf(entry, s, sizeof(s), browser->hists);
618 slsmg_write_nstring(s, width); 668 slsmg_write_nstring(s, width);
619 ++row; 669 ++row;
620 ++printed; 670 ++printed;
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 26b5b652a8c..3c16ab50e0f 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -36,6 +36,57 @@ static void perf_gtk__resize_window(GtkWidget *window)
36 gtk_window_resize(GTK_WINDOW(window), width, height); 36 gtk_window_resize(GTK_WINDOW(window), width, height);
37} 37}
38 38
39static const char *perf_gtk__get_percent_color(double percent)
40{
41 if (percent >= MIN_RED)
42 return "<span fgcolor='red'>";
43 if (percent >= MIN_GREEN)
44 return "<span fgcolor='dark green'>";
45 return NULL;
46}
47
48#define HPP__COLOR_FN(_name, _field) \
49static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, \
50 struct hist_entry *he) \
51{ \
52 double percent = 100.0 * he->_field / hpp->total_period; \
53 const char *markup; \
54 int ret = 0; \
55 \
56 markup = perf_gtk__get_percent_color(percent); \
57 if (markup) \
58 ret += scnprintf(hpp->buf, hpp->size, "%s", markup); \
59 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "%5.2f%%", percent); \
60 if (markup) \
61 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "</span>"); \
62 \
63 return ret; \
64}
65
66HPP__COLOR_FN(overhead, period)
67HPP__COLOR_FN(overhead_sys, period_sys)
68HPP__COLOR_FN(overhead_us, period_us)
69HPP__COLOR_FN(overhead_guest_sys, period_guest_sys)
70HPP__COLOR_FN(overhead_guest_us, period_guest_us)
71
72#undef HPP__COLOR_FN
73
74void perf_gtk__init_hpp(void)
75{
76 perf_hpp__init(false, false);
77
78 perf_hpp__format[PERF_HPP__OVERHEAD].color =
79 perf_gtk__hpp_color_overhead;
80 perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color =
81 perf_gtk__hpp_color_overhead_sys;
82 perf_hpp__format[PERF_HPP__OVERHEAD_US].color =
83 perf_gtk__hpp_color_overhead_us;
84 perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_SYS].color =
85 perf_gtk__hpp_color_overhead_guest_sys;
86 perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_US].color =
87 perf_gtk__hpp_color_overhead_guest_us;
88}
89
39static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) 90static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
40{ 91{
41 GType col_types[MAX_COLUMNS]; 92 GType col_types[MAX_COLUMNS];
@@ -43,15 +94,25 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
43 struct sort_entry *se; 94 struct sort_entry *se;
44 GtkListStore *store; 95 GtkListStore *store;
45 struct rb_node *nd; 96 struct rb_node *nd;
46 u64 total_period;
47 GtkWidget *view; 97 GtkWidget *view;
48 int col_idx; 98 int i, col_idx;
49 int nr_cols; 99 int nr_cols;
100 char s[512];
101
102 struct perf_hpp hpp = {
103 .buf = s,
104 .size = sizeof(s),
105 .total_period = hists->stats.total_period,
106 };
50 107
51 nr_cols = 0; 108 nr_cols = 0;
52 109
53 /* The percentage column */ 110 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
54 col_types[nr_cols++] = G_TYPE_STRING; 111 if (!perf_hpp__format[i].cond)
112 continue;
113
114 col_types[nr_cols++] = G_TYPE_STRING;
115 }
55 116
56 list_for_each_entry(se, &hist_entry__sort_list, list) { 117 list_for_each_entry(se, &hist_entry__sort_list, list) {
57 if (se->elide) 118 if (se->elide)
@@ -68,11 +129,17 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
68 129
69 col_idx = 0; 130 col_idx = 0;
70 131
71 /* The percentage column */ 132 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
72 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), 133 if (!perf_hpp__format[i].cond)
73 -1, "Overhead (%)", 134 continue;
74 renderer, "text", 135
75 col_idx++, NULL); 136 perf_hpp__format[i].header(&hpp);
137
138 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
139 -1, s,
140 renderer, "markup",
141 col_idx++, NULL);
142 }
76 143
77 list_for_each_entry(se, &hist_entry__sort_list, list) { 144 list_for_each_entry(se, &hist_entry__sort_list, list) {
78 if (se->elide) 145 if (se->elide)
@@ -88,13 +155,9 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
88 155
89 g_object_unref(GTK_TREE_MODEL(store)); 156 g_object_unref(GTK_TREE_MODEL(store));
90 157
91 total_period = hists->stats.total_period;
92
93 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { 158 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
94 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 159 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
95 GtkTreeIter iter; 160 GtkTreeIter iter;
96 double percent;
97 char s[512];
98 161
99 if (h->filtered) 162 if (h->filtered)
100 continue; 163 continue;
@@ -103,11 +166,17 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
103 166
104 col_idx = 0; 167 col_idx = 0;
105 168
106 percent = (h->period * 100.0) / total_period; 169 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
170 if (!perf_hpp__format[i].cond)
171 continue;
107 172
108 snprintf(s, ARRAY_SIZE(s), "%.2f", percent); 173 if (perf_hpp__format[i].color)
174 perf_hpp__format[i].color(&hpp, h);
175 else
176 perf_hpp__format[i].entry(&hpp, h);
109 177
110 gtk_list_store_set(store, &iter, col_idx++, s, -1); 178 gtk_list_store_set(store, &iter, col_idx++, s, -1);
179 }
111 180
112 list_for_each_entry(se, &hist_entry__sort_list, list) { 181 list_for_each_entry(se, &hist_entry__sort_list, list) {
113 if (se->elide) 182 if (se->elide)
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 793cb6116dd..687af0bba18 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -30,6 +30,7 @@ struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window);
30int perf_gtk__deactivate_context(struct perf_gtk_context **ctx); 30int perf_gtk__deactivate_context(struct perf_gtk_context **ctx);
31 31
32void perf_gtk__init_helpline(void); 32void perf_gtk__init_helpline(void);
33void perf_gtk__init_hpp(void);
33 34
34#ifndef HAVE_GTK_INFO_BAR 35#ifndef HAVE_GTK_INFO_BAR
35static inline GtkWidget *perf_gtk__setup_info_bar(void) 36static inline GtkWidget *perf_gtk__setup_info_bar(void)
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c
index ec1ee26b485..26429437e19 100644
--- a/tools/perf/ui/gtk/setup.c
+++ b/tools/perf/ui/gtk/setup.c
@@ -8,6 +8,7 @@ int perf_gtk__init(void)
8{ 8{
9 perf_error__register(&perf_gtk_eops); 9 perf_error__register(&perf_gtk_eops);
10 perf_gtk__init_helpline(); 10 perf_gtk__init_helpline();
11 perf_gtk__init_hpp();
11 return gtk_init_check(NULL, NULL) ? 0 : -1; 12 return gtk_init_check(NULL, NULL) ? 0 : -1;
12} 13}
13 14
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
new file mode 100644
index 00000000000..031b349a3f8
--- /dev/null
+++ b/tools/perf/ui/hist.c
@@ -0,0 +1,389 @@
1#include <math.h>
2
3#include "../util/hist.h"
4#include "../util/util.h"
5#include "../util/sort.h"
6
7
8/* hist period print (hpp) functions */
9static int hpp__header_overhead(struct perf_hpp *hpp)
10{
11 const char *fmt = hpp->ptr ? "Baseline" : "Overhead";
12
13 return scnprintf(hpp->buf, hpp->size, fmt);
14}
15
16static int hpp__width_overhead(struct perf_hpp *hpp __used)
17{
18 return 8;
19}
20
21static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
22{
23 double percent = 100.0 * he->period / hpp->total_period;
24
25 if (hpp->ptr) {
26 struct hists *old_hists = hpp->ptr;
27 u64 total_period = old_hists->stats.total_period;
28 u64 base_period = he->pair ? he->pair->period : 0;
29
30 if (total_period)
31 percent = 100.0 * base_period / total_period;
32 else
33 percent = 0.0;
34 }
35
36 return percent_color_snprintf(hpp->buf, hpp->size, " %5.2f%%", percent);
37}
38
39static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
40{
41 double percent = 100.0 * he->period / hpp->total_period;
42 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %5.2f%%";
43
44 if (hpp->ptr) {
45 struct hists *old_hists = hpp->ptr;
46 u64 total_period = old_hists->stats.total_period;
47 u64 base_period = he->pair ? he->pair->period : 0;
48
49 if (total_period)
50 percent = 100.0 * base_period / total_period;
51 else
52 percent = 0.0;
53 }
54
55 return scnprintf(hpp->buf, hpp->size, fmt, percent);
56}
57
58static int hpp__header_overhead_sys(struct perf_hpp *hpp)
59{
60 const char *fmt = symbol_conf.field_sep ? "%s" : "%6s";
61
62 return scnprintf(hpp->buf, hpp->size, fmt, "sys");
63}
64
65static int hpp__width_overhead_sys(struct perf_hpp *hpp __used)
66{
67 return 6;
68}
69
70static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
71{
72 double percent = 100.0 * he->period_sys / hpp->total_period;
73 return percent_color_snprintf(hpp->buf, hpp->size, "%5.2f%%", percent);
74}
75
76static int hpp__entry_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
77{
78 double percent = 100.0 * he->period_sys / hpp->total_period;
79 const char *fmt = symbol_conf.field_sep ? "%.2f" : "%5.2f%%";
80
81 return scnprintf(hpp->buf, hpp->size, fmt, percent);
82}
83
84static int hpp__header_overhead_us(struct perf_hpp *hpp)
85{
86 const char *fmt = symbol_conf.field_sep ? "%s" : "%6s";
87
88 return scnprintf(hpp->buf, hpp->size, fmt, "user");
89}
90
91static int hpp__width_overhead_us(struct perf_hpp *hpp __used)
92{
93 return 6;
94}
95
96static int hpp__color_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
97{
98 double percent = 100.0 * he->period_us / hpp->total_period;
99 return percent_color_snprintf(hpp->buf, hpp->size, "%5.2f%%", percent);
100}
101
102static int hpp__entry_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
103{
104 double percent = 100.0 * he->period_us / hpp->total_period;
105 const char *fmt = symbol_conf.field_sep ? "%.2f" : "%5.2f%%";
106
107 return scnprintf(hpp->buf, hpp->size, fmt, percent);
108}
109
110static int hpp__header_overhead_guest_sys(struct perf_hpp *hpp)
111{
112 return scnprintf(hpp->buf, hpp->size, "guest sys");
113}
114
115static int hpp__width_overhead_guest_sys(struct perf_hpp *hpp __used)
116{
117 return 9;
118}
119
120static int hpp__color_overhead_guest_sys(struct perf_hpp *hpp,
121 struct hist_entry *he)
122{
123 double percent = 100.0 * he->period_guest_sys / hpp->total_period;
124 return percent_color_snprintf(hpp->buf, hpp->size, " %5.2f%% ", percent);
125}
126
127static int hpp__entry_overhead_guest_sys(struct perf_hpp *hpp,
128 struct hist_entry *he)
129{
130 double percent = 100.0 * he->period_guest_sys / hpp->total_period;
131 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %5.2f%% ";
132
133 return scnprintf(hpp->buf, hpp->size, fmt, percent);
134}
135
136static int hpp__header_overhead_guest_us(struct perf_hpp *hpp)
137{
138 return scnprintf(hpp->buf, hpp->size, "guest usr");
139}
140
141static int hpp__width_overhead_guest_us(struct perf_hpp *hpp __used)
142{
143 return 9;
144}
145
146static int hpp__color_overhead_guest_us(struct perf_hpp *hpp,
147 struct hist_entry *he)
148{
149 double percent = 100.0 * he->period_guest_us / hpp->total_period;
150 return percent_color_snprintf(hpp->buf, hpp->size, " %5.2f%% ", percent);
151}
152
153static int hpp__entry_overhead_guest_us(struct perf_hpp *hpp,
154 struct hist_entry *he)
155{
156 double percent = 100.0 * he->period_guest_us / hpp->total_period;
157 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %5.2f%% ";
158
159 return scnprintf(hpp->buf, hpp->size, fmt, percent);
160}
161
162static int hpp__header_samples(struct perf_hpp *hpp)
163{
164 const char *fmt = symbol_conf.field_sep ? "%s" : "%11s";
165
166 return scnprintf(hpp->buf, hpp->size, fmt, "Samples");
167}
168
169static int hpp__width_samples(struct perf_hpp *hpp __used)
170{
171 return 11;
172}
173
174static int hpp__entry_samples(struct perf_hpp *hpp, struct hist_entry *he)
175{
176 const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%11" PRIu64;
177
178 return scnprintf(hpp->buf, hpp->size, fmt, he->nr_events);
179}
180
181static int hpp__header_period(struct perf_hpp *hpp)
182{
183 const char *fmt = symbol_conf.field_sep ? "%s" : "%12s";
184
185 return scnprintf(hpp->buf, hpp->size, fmt, "Period");
186}
187
188static int hpp__width_period(struct perf_hpp *hpp __used)
189{
190 return 12;
191}
192
193static int hpp__entry_period(struct perf_hpp *hpp, struct hist_entry *he)
194{
195 const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64;
196
197 return scnprintf(hpp->buf, hpp->size, fmt, he->period);
198}
199
200static int hpp__header_delta(struct perf_hpp *hpp)
201{
202 const char *fmt = symbol_conf.field_sep ? "%s" : "%7s";
203
204 return scnprintf(hpp->buf, hpp->size, fmt, "Delta");
205}
206
207static int hpp__width_delta(struct perf_hpp *hpp __used)
208{
209 return 7;
210}
211
212static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he)
213{
214 struct hists *pair_hists = hpp->ptr;
215 u64 old_total, new_total;
216 double old_percent = 0, new_percent = 0;
217 double diff;
218 const char *fmt = symbol_conf.field_sep ? "%s" : "%7.7s";
219 char buf[32] = " ";
220
221 old_total = pair_hists->stats.total_period;
222 if (old_total > 0 && he->pair)
223 old_percent = 100.0 * he->pair->period / old_total;
224
225 new_total = hpp->total_period;
226 if (new_total > 0)
227 new_percent = 100.0 * he->period / new_total;
228
229 diff = new_percent - old_percent;
230 if (fabs(diff) >= 0.01)
231 scnprintf(buf, sizeof(buf), "%+4.2F%%", diff);
232
233 return scnprintf(hpp->buf, hpp->size, fmt, buf);
234}
235
236static int hpp__header_displ(struct perf_hpp *hpp)
237{
238 return scnprintf(hpp->buf, hpp->size, "Displ.");
239}
240
241static int hpp__width_displ(struct perf_hpp *hpp __used)
242{
243 return 6;
244}
245
246static int hpp__entry_displ(struct perf_hpp *hpp, struct hist_entry *he __used)
247{
248 const char *fmt = symbol_conf.field_sep ? "%s" : "%6.6s";
249 char buf[32] = " ";
250
251 if (hpp->displacement)
252 scnprintf(buf, sizeof(buf), "%+4ld", hpp->displacement);
253
254 return scnprintf(hpp->buf, hpp->size, fmt, buf);
255}
256
257#define HPP__COLOR_PRINT_FNS(_name) \
258 .header = hpp__header_ ## _name, \
259 .width = hpp__width_ ## _name, \
260 .color = hpp__color_ ## _name, \
261 .entry = hpp__entry_ ## _name
262
263#define HPP__PRINT_FNS(_name) \
264 .header = hpp__header_ ## _name, \
265 .width = hpp__width_ ## _name, \
266 .entry = hpp__entry_ ## _name
267
268struct perf_hpp_fmt perf_hpp__format[] = {
269 { .cond = true, HPP__COLOR_PRINT_FNS(overhead) },
270 { .cond = false, HPP__COLOR_PRINT_FNS(overhead_sys) },
271 { .cond = false, HPP__COLOR_PRINT_FNS(overhead_us) },
272 { .cond = false, HPP__COLOR_PRINT_FNS(overhead_guest_sys) },
273 { .cond = false, HPP__COLOR_PRINT_FNS(overhead_guest_us) },
274 { .cond = false, HPP__PRINT_FNS(samples) },
275 { .cond = false, HPP__PRINT_FNS(period) },
276 { .cond = false, HPP__PRINT_FNS(delta) },
277 { .cond = false, HPP__PRINT_FNS(displ) }
278};
279
280#undef HPP__COLOR_PRINT_FNS
281#undef HPP__PRINT_FNS
282
283void perf_hpp__init(bool need_pair, bool show_displacement)
284{
285 if (symbol_conf.show_cpu_utilization) {
286 perf_hpp__format[PERF_HPP__OVERHEAD_SYS].cond = true;
287 perf_hpp__format[PERF_HPP__OVERHEAD_US].cond = true;
288
289 if (perf_guest) {
290 perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_SYS].cond = true;
291 perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_US].cond = true;
292 }
293 }
294
295 if (symbol_conf.show_nr_samples)
296 perf_hpp__format[PERF_HPP__SAMPLES].cond = true;
297
298 if (symbol_conf.show_total_period)
299 perf_hpp__format[PERF_HPP__PERIOD].cond = true;
300
301 if (need_pair) {
302 perf_hpp__format[PERF_HPP__DELTA].cond = true;
303
304 if (show_displacement)
305 perf_hpp__format[PERF_HPP__DISPL].cond = true;
306 }
307}
308
309static inline void advance_hpp(struct perf_hpp *hpp, int inc)
310{
311 hpp->buf += inc;
312 hpp->size -= inc;
313}
314
315int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he,
316 bool color)
317{
318 const char *sep = symbol_conf.field_sep;
319 char *start = hpp->buf;
320 int i, ret;
321
322 if (symbol_conf.exclude_other && !he->parent)
323 return 0;
324
325 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
326 if (!perf_hpp__format[i].cond)
327 continue;
328
329 if (!sep || i > 0) {
330 ret = scnprintf(hpp->buf, hpp->size, "%s", sep ?: " ");
331 advance_hpp(hpp, ret);
332 }
333
334 if (color && perf_hpp__format[i].color)
335 ret = perf_hpp__format[i].color(hpp, he);
336 else
337 ret = perf_hpp__format[i].entry(hpp, he);
338
339 advance_hpp(hpp, ret);
340 }
341
342 return hpp->buf - start;
343}
344
345int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size,
346 struct hists *hists)
347{
348 const char *sep = symbol_conf.field_sep;
349 struct sort_entry *se;
350 int ret = 0;
351
352 list_for_each_entry(se, &hist_entry__sort_list, list) {
353 if (se->elide)
354 continue;
355
356 ret += scnprintf(s + ret, size - ret, "%s", sep ?: " ");
357 ret += se->se_snprintf(he, s + ret, size - ret,
358 hists__col_len(hists, se->se_width_idx));
359 }
360
361 return ret;
362}
363
364/*
365 * See hists__fprintf to match the column widths
366 */
367unsigned int hists__sort_list_width(struct hists *hists)
368{
369 struct sort_entry *se;
370 int i, ret = 0;
371
372 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
373 if (!perf_hpp__format[i].cond)
374 continue;
375 if (i)
376 ret += 2;
377
378 ret += perf_hpp__format[i].width(NULL);
379 }
380
381 list_for_each_entry(se, &hist_entry__sort_list, list)
382 if (!se->elide)
383 ret += 2 + hists__col_len(hists, se->se_width_idx);
384
385 if (verbose) /* Addr + origin */
386 ret += 3 + BITS_PER_LONG / 4;
387
388 return ret;
389}
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index c7820e56966..bd7d460f844 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -1,8 +1,8 @@
1#include <pthread.h> 1#include <pthread.h>
2 2
3#include "../cache.h" 3#include "../util/cache.h"
4#include "../debug.h" 4#include "../util/debug.h"
5 5#include "../util/hist.h"
6 6
7pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; 7pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
8 8
@@ -29,6 +29,8 @@ void setup_browser(bool fallback_to_pager)
29 use_browser = 0; 29 use_browser = 0;
30 if (fallback_to_pager) 30 if (fallback_to_pager)
31 setup_pager(); 31 setup_pager();
32
33 perf_hpp__init(false, false);
32 break; 34 break;
33 } 35 }
34} 36}
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 9bf7e9e5a72..882461a4283 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -1,5 +1,4 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <math.h>
3 2
4#include "../../util/util.h" 3#include "../../util/util.h"
5#include "../../util/hist.h" 4#include "../../util/hist.h"
@@ -291,138 +290,6 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
291 return 0; 290 return 0;
292} 291}
293 292
294static int hist_entry__period_snprintf(struct hist_entry *he, char *s,
295 size_t size, struct hists *pair_hists,
296 bool show_displacement, long displacement,
297 bool color, u64 total_period)
298{
299 u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
300 u64 nr_events;
301 const char *sep = symbol_conf.field_sep;
302 int ret;
303
304 if (symbol_conf.exclude_other && !he->parent)
305 return 0;
306
307 if (pair_hists) {
308 period = he->pair ? he->pair->period : 0;
309 nr_events = he->pair ? he->pair->nr_events : 0;
310 total = pair_hists->stats.total_period;
311 period_sys = he->pair ? he->pair->period_sys : 0;
312 period_us = he->pair ? he->pair->period_us : 0;
313 period_guest_sys = he->pair ? he->pair->period_guest_sys : 0;
314 period_guest_us = he->pair ? he->pair->period_guest_us : 0;
315 } else {
316 period = he->period;
317 nr_events = he->nr_events;
318 total = total_period;
319 period_sys = he->period_sys;
320 period_us = he->period_us;
321 period_guest_sys = he->period_guest_sys;
322 period_guest_us = he->period_guest_us;
323 }
324
325 if (total) {
326 if (color)
327 ret = percent_color_snprintf(s, size,
328 sep ? "%.2f" : " %6.2f%%",
329 (period * 100.0) / total);
330 else
331 ret = scnprintf(s, size, sep ? "%.2f" : " %6.2f%%",
332 (period * 100.0) / total);
333 if (symbol_conf.show_cpu_utilization) {
334 ret += percent_color_snprintf(s + ret, size - ret,
335 sep ? "%.2f" : " %6.2f%%",
336 (period_sys * 100.0) / total);
337 ret += percent_color_snprintf(s + ret, size - ret,
338 sep ? "%.2f" : " %6.2f%%",
339 (period_us * 100.0) / total);
340 if (perf_guest) {
341 ret += percent_color_snprintf(s + ret,
342 size - ret,
343 sep ? "%.2f" : " %6.2f%%",
344 (period_guest_sys * 100.0) /
345 total);
346 ret += percent_color_snprintf(s + ret,
347 size - ret,
348 sep ? "%.2f" : " %6.2f%%",
349 (period_guest_us * 100.0) /
350 total);
351 }
352 }
353 } else
354 ret = scnprintf(s, size, sep ? "%" PRIu64 : "%12" PRIu64 " ", period);
355
356 if (symbol_conf.show_nr_samples) {
357 if (sep)
358 ret += scnprintf(s + ret, size - ret, "%c%" PRIu64, *sep, nr_events);
359 else
360 ret += scnprintf(s + ret, size - ret, "%11" PRIu64, nr_events);
361 }
362
363 if (symbol_conf.show_total_period) {
364 if (sep)
365 ret += scnprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period);
366 else
367 ret += scnprintf(s + ret, size - ret, " %12" PRIu64, period);
368 }
369
370 if (pair_hists) {
371 char bf[32];
372 double old_percent = 0, new_percent = 0, diff;
373
374 if (total > 0)
375 old_percent = (period * 100.0) / total;
376 if (total_period > 0)
377 new_percent = (he->period * 100.0) / total_period;
378
379 diff = new_percent - old_percent;
380
381 if (fabs(diff) >= 0.01)
382 scnprintf(bf, sizeof(bf), "%+4.2F%%", diff);
383 else
384 scnprintf(bf, sizeof(bf), " ");
385
386 if (sep)
387 ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf);
388 else
389 ret += scnprintf(s + ret, size - ret, "%11.11s", bf);
390
391 if (show_displacement) {
392 if (displacement)
393 scnprintf(bf, sizeof(bf), "%+4ld", displacement);
394 else
395 scnprintf(bf, sizeof(bf), " ");
396
397 if (sep)
398 ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf);
399 else
400 ret += scnprintf(s + ret, size - ret, "%6.6s", bf);
401 }
402 }
403
404 return ret;
405}
406
407int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size,
408 struct hists *hists)
409{
410 const char *sep = symbol_conf.field_sep;
411 struct sort_entry *se;
412 int ret = 0;
413
414 list_for_each_entry(se, &hist_entry__sort_list, list) {
415 if (se->elide)
416 continue;
417
418 ret += scnprintf(s + ret, size - ret, "%s", sep ?: " ");
419 ret += se->se_snprintf(he, s + ret, size - ret,
420 hists__col_len(hists, se->se_width_idx));
421 }
422
423 return ret;
424}
425
426static size_t hist_entry__callchain_fprintf(struct hist_entry *he, 293static size_t hist_entry__callchain_fprintf(struct hist_entry *he,
427 struct hists *hists, 294 struct hists *hists,
428 u64 total_period, FILE *fp) 295 u64 total_period, FILE *fp)
@@ -441,18 +308,23 @@ static size_t hist_entry__callchain_fprintf(struct hist_entry *he,
441 308
442static int hist_entry__fprintf(struct hist_entry *he, size_t size, 309static int hist_entry__fprintf(struct hist_entry *he, size_t size,
443 struct hists *hists, struct hists *pair_hists, 310 struct hists *hists, struct hists *pair_hists,
444 bool show_displacement, long displacement, 311 long displacement, u64 total_period, FILE *fp)
445 u64 total_period, FILE *fp)
446{ 312{
447 char bf[512]; 313 char bf[512];
448 int ret; 314 int ret;
315 struct perf_hpp hpp = {
316 .buf = bf,
317 .size = size,
318 .total_period = total_period,
319 .displacement = displacement,
320 .ptr = pair_hists,
321 };
322 bool color = !symbol_conf.field_sep;
449 323
450 if (size == 0 || size > sizeof(bf)) 324 if (size == 0 || size > sizeof(bf))
451 size = sizeof(bf); 325 size = hpp.size = sizeof(bf);
452 326
453 ret = hist_entry__period_snprintf(he, bf, size, pair_hists, 327 ret = hist_entry__period_snprintf(&hpp, he, color);
454 show_displacement, displacement,
455 true, total_period);
456 hist_entry__sort_snprintf(he, bf + ret, size - ret, hists); 328 hist_entry__sort_snprintf(he, bf + ret, size - ret, hists);
457 329
458 ret = fprintf(fp, "%s\n", bf); 330 ret = fprintf(fp, "%s\n", bf);
@@ -477,59 +349,29 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
477 unsigned int width; 349 unsigned int width;
478 const char *sep = symbol_conf.field_sep; 350 const char *sep = symbol_conf.field_sep;
479 const char *col_width = symbol_conf.col_width_list_str; 351 const char *col_width = symbol_conf.col_width_list_str;
480 int nr_rows = 0; 352 int idx, nr_rows = 0;
353 char bf[64];
354 struct perf_hpp dummy_hpp = {
355 .buf = bf,
356 .size = sizeof(bf),
357 .ptr = pair,
358 };
481 359
482 init_rem_hits(); 360 init_rem_hits();
483 361
484 if (!show_header) 362 if (!show_header)
485 goto print_entries; 363 goto print_entries;
486 364
487 fprintf(fp, "# %s", pair ? "Baseline" : "Overhead"); 365 fprintf(fp, "# ");
488 366 for (idx = 0; idx < PERF_HPP__MAX_INDEX; idx++) {
489 if (symbol_conf.show_cpu_utilization) { 367 if (!perf_hpp__format[idx].cond)
490 if (sep) { 368 continue;
491 ret += fprintf(fp, "%csys", *sep);
492 ret += fprintf(fp, "%cus", *sep);
493 if (perf_guest) {
494 ret += fprintf(fp, "%cguest sys", *sep);
495 ret += fprintf(fp, "%cguest us", *sep);
496 }
497 } else {
498 ret += fprintf(fp, " sys ");
499 ret += fprintf(fp, " us ");
500 if (perf_guest) {
501 ret += fprintf(fp, " guest sys ");
502 ret += fprintf(fp, " guest us ");
503 }
504 }
505 }
506
507 if (symbol_conf.show_nr_samples) {
508 if (sep)
509 fprintf(fp, "%cSamples", *sep);
510 else
511 fputs(" Samples ", fp);
512 }
513
514 if (symbol_conf.show_total_period) {
515 if (sep)
516 ret += fprintf(fp, "%cPeriod", *sep);
517 else
518 ret += fprintf(fp, " Period ");
519 }
520 369
521 if (pair) { 370 if (idx)
522 if (sep) 371 fprintf(fp, "%s", sep ?: " ");
523 ret += fprintf(fp, "%cDelta", *sep);
524 else
525 ret += fprintf(fp, " Delta ");
526 372
527 if (show_displacement) { 373 perf_hpp__format[idx].header(&dummy_hpp);
528 if (sep) 374 fprintf(fp, "%s", bf);
529 ret += fprintf(fp, "%cDisplacement", *sep);
530 else
531 ret += fprintf(fp, " Displ");
532 }
533 } 375 }
534 376
535 list_for_each_entry(se, &hist_entry__sort_list, list) { 377 list_for_each_entry(se, &hist_entry__sort_list, list) {
@@ -561,18 +403,21 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
561 if (sep) 403 if (sep)
562 goto print_entries; 404 goto print_entries;
563 405
564 fprintf(fp, "# ........"); 406 fprintf(fp, "# ");
565 if (symbol_conf.show_cpu_utilization) 407 for (idx = 0; idx < PERF_HPP__MAX_INDEX; idx++) {
566 fprintf(fp, " ....... ......."); 408 unsigned int i;
567 if (symbol_conf.show_nr_samples) 409
568 fprintf(fp, " .........."); 410 if (!perf_hpp__format[idx].cond)
569 if (symbol_conf.show_total_period) 411 continue;
570 fprintf(fp, " ............"); 412
571 if (pair) { 413 if (idx)
572 fprintf(fp, " .........."); 414 fprintf(fp, "%s", sep ?: " ");
573 if (show_displacement) 415
574 fprintf(fp, " ....."); 416 width = perf_hpp__format[idx].width(&dummy_hpp);
417 for (i = 0; i < width; i++)
418 fprintf(fp, ".");
575 } 419 }
420
576 list_for_each_entry(se, &hist_entry__sort_list, list) { 421 list_for_each_entry(se, &hist_entry__sort_list, list) {
577 unsigned int i; 422 unsigned int i;
578 423
@@ -612,8 +457,8 @@ print_entries:
612 displacement = 0; 457 displacement = 0;
613 ++position; 458 ++position;
614 } 459 }
615 ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement, 460 ret += hist_entry__fprintf(h, max_cols, hists, pair, displacement,
616 displacement, total_period, fp); 461 total_period, fp);
617 462
618 if (max_rows && ++nr_rows >= max_rows) 463 if (max_rows && ++nr_rows >= max_rows)
619 goto out; 464 goto out;
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index 4c936e09931..4dc0887c04f 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -15,6 +15,8 @@ static volatile int ui__need_resize;
15 15
16extern struct perf_error_ops perf_tui_eops; 16extern struct perf_error_ops perf_tui_eops;
17 17
18extern void hist_browser__init_hpp(void);
19
18void ui__refresh_dimensions(bool force) 20void ui__refresh_dimensions(bool force)
19{ 21{
20 if (force || ui__need_resize) { 22 if (force || ui__need_resize) {
@@ -124,6 +126,8 @@ int ui__init(void)
124 signal(SIGTERM, ui__signal); 126 signal(SIGTERM, ui__signal);
125 127
126 perf_error__register(&perf_tui_eops); 128 perf_error__register(&perf_tui_eops);
129
130 hist_browser__init_hpp();
127out: 131out:
128 return err; 132 return err;
129} 133}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 51ef69c9841..04eafd3939d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -984,7 +984,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
984 int context) 984 int context)
985{ 985{
986 struct dso *dso = map->dso; 986 struct dso *dso = map->dso;
987 const char *filename = dso->long_name, *d_filename; 987 char *filename;
988 const char *d_filename;
988 struct annotation *notes = symbol__annotation(sym); 989 struct annotation *notes = symbol__annotation(sym);
989 struct disasm_line *pos, *queue = NULL; 990 struct disasm_line *pos, *queue = NULL;
990 u64 start = map__rip_2objdump(map, sym->start); 991 u64 start = map__rip_2objdump(map, sym->start);
@@ -992,6 +993,10 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
992 int more = 0; 993 int more = 0;
993 u64 len; 994 u64 len;
994 995
996 filename = strdup(dso->long_name);
997 if (!filename)
998 return -ENOMEM;
999
995 if (full_paths) 1000 if (full_paths)
996 d_filename = filename; 1001 d_filename = filename;
997 else 1002 else
@@ -1042,6 +1047,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
1042 } 1047 }
1043 } 1048 }
1044 1049
1050 free(filename);
1051
1045 return more; 1052 return more;
1046} 1053}
1047 1054
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index b1817f15bb8..0ba65ad07cd 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -563,39 +563,6 @@ void hists__output_resort_threaded(struct hists *hists)
563 return __hists__output_resort(hists, true); 563 return __hists__output_resort(hists, true);
564} 564}
565 565
566/*
567 * See hists__fprintf to match the column widths
568 */
569unsigned int hists__sort_list_width(struct hists *hists)
570{
571 struct sort_entry *se;
572 int ret = 9; /* total % */
573
574 if (symbol_conf.show_cpu_utilization) {
575 ret += 7; /* count_sys % */
576 ret += 6; /* count_us % */
577 if (perf_guest) {
578 ret += 13; /* count_guest_sys % */
579 ret += 12; /* count_guest_us % */
580 }
581 }
582
583 if (symbol_conf.show_nr_samples)
584 ret += 11;
585
586 if (symbol_conf.show_total_period)
587 ret += 13;
588
589 list_for_each_entry(se, &hist_entry__sort_list, list)
590 if (!se->elide)
591 ret += 2 + hists__col_len(hists, se->se_width_idx);
592
593 if (verbose) /* Addr + origin */
594 ret += 3 + BITS_PER_LONG / 4;
595
596 return ret;
597}
598
599static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h, 566static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
600 enum hist_filter filter) 567 enum hist_filter filter)
601{ 568{
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 2e650ffb7d2..4146f51124f 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -115,6 +115,43 @@ bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len);
115void hists__reset_col_len(struct hists *hists); 115void hists__reset_col_len(struct hists *hists);
116void hists__calc_col_len(struct hists *hists, struct hist_entry *he); 116void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
117 117
118struct perf_hpp {
119 char *buf;
120 size_t size;
121 u64 total_period;
122 const char *sep;
123 long displacement;
124 void *ptr;
125};
126
127struct perf_hpp_fmt {
128 bool cond;
129 int (*header)(struct perf_hpp *hpp);
130 int (*width)(struct perf_hpp *hpp);
131 int (*color)(struct perf_hpp *hpp, struct hist_entry *he);
132 int (*entry)(struct perf_hpp *hpp, struct hist_entry *he);
133};
134
135extern struct perf_hpp_fmt perf_hpp__format[];
136
137enum {
138 PERF_HPP__OVERHEAD,
139 PERF_HPP__OVERHEAD_SYS,
140 PERF_HPP__OVERHEAD_US,
141 PERF_HPP__OVERHEAD_GUEST_SYS,
142 PERF_HPP__OVERHEAD_GUEST_US,
143 PERF_HPP__SAMPLES,
144 PERF_HPP__PERIOD,
145 PERF_HPP__DELTA,
146 PERF_HPP__DISPL,
147
148 PERF_HPP__MAX_INDEX
149};
150
151void perf_hpp__init(bool need_pair, bool show_displacement);
152int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he,
153 bool color);
154
118struct perf_evlist; 155struct perf_evlist;
119 156
120#ifdef NO_NEWT_SUPPORT 157#ifdef NO_NEWT_SUPPORT
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h
index b6842c1d02a..4af9a10cc2d 100644
--- a/tools/perf/util/include/linux/kernel.h
+++ b/tools/perf/util/include/linux/kernel.h
@@ -47,8 +47,12 @@
47#endif 47#endif
48 48
49#ifndef BUG_ON 49#ifndef BUG_ON
50#ifdef NDEBUG
51#define BUG_ON(cond) do { if (cond) {} } while (0)
52#else
50#define BUG_ON(cond) assert(!(cond)) 53#define BUG_ON(cond) assert(!(cond))
51#endif 54#endif
55#endif
52 56
53/* 57/*
54 * Both need more care to handle endianness 58 * Both need more care to handle endianness
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 0dda25d82d0..e8c72de0f70 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2307,10 +2307,17 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
2307 function = NULL; 2307 function = NULL;
2308 } 2308 }
2309 if (!pev->group) { 2309 if (!pev->group) {
2310 char *ptr1, *ptr2; 2310 char *ptr1, *ptr2, *exec_copy;
2311 2311
2312 pev->group = zalloc(sizeof(char *) * 64); 2312 pev->group = zalloc(sizeof(char *) * 64);
2313 ptr1 = strdup(basename(exec)); 2313 exec_copy = strdup(exec);
2314 if (!exec_copy) {
2315 ret = -ENOMEM;
2316 pr_warning("Failed to copy exec string.\n");
2317 goto out;
2318 }
2319
2320 ptr1 = strdup(basename(exec_copy));
2314 if (ptr1) { 2321 if (ptr1) {
2315 ptr2 = strpbrk(ptr1, "-._"); 2322 ptr2 = strpbrk(ptr1, "-._");
2316 if (ptr2) 2323 if (ptr2)
@@ -2319,6 +2326,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
2319 ptr1); 2326 ptr1);
2320 free(ptr1); 2327 free(ptr1);
2321 } 2328 }
2329 free(exec_copy);
2322 } 2330 }
2323 free(pp->function); 2331 free(pp->function);
2324 pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); 2332 pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS);
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index d3b330cbc3e..41a15dac412 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -10,9 +10,7 @@
10#include <linux/rbtree.h> 10#include <linux/rbtree.h>
11#include <stdio.h> 11#include <stdio.h>
12#include <byteswap.h> 12#include <byteswap.h>
13#if defined(__BIONIC__)
14#include <libgen.h> 13#include <libgen.h>
15#endif
16 14
17#ifndef NO_LIBELF_SUPPORT 15#ifndef NO_LIBELF_SUPPORT
18#include <libelf.h> 16#include <libelf.h>