aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/ui/browsers/hists.c8
-rw-r--r--tools/perf/ui/gtk/hists.c8
-rw-r--r--tools/perf/ui/stdio/hist.c35
-rw-r--r--tools/perf/util/callchain.c29
-rw-r--r--tools/perf/util/callchain.h4
5 files changed, 57 insertions, 27 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index fa9eb92c9e24..0b18857a36e8 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -592,7 +592,6 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
592 while (node) { 592 while (node) {
593 struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); 593 struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
594 struct rb_node *next = rb_next(node); 594 struct rb_node *next = rb_next(node);
595 u64 cumul = callchain_cumul_hits(child);
596 struct callchain_list *chain; 595 struct callchain_list *chain;
597 char folded_sign = ' '; 596 char folded_sign = ' ';
598 int first = true; 597 int first = true;
@@ -619,9 +618,12 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
619 browser->show_dso); 618 browser->show_dso);
620 619
621 if (was_first && need_percent) { 620 if (was_first && need_percent) {
622 double percent = cumul * 100.0 / total; 621 char buf[64];
623 622
624 if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) 623 callchain_node__scnprintf_value(child, buf, sizeof(buf),
624 total);
625
626 if (asprintf(&alloc_str, "%s %s", buf, str) < 0)
625 str = "Not enough memory!"; 627 str = "Not enough memory!";
626 else 628 else
627 str = alloc_str; 629 str = alloc_str;
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 4b3585eed1e8..cff7bb9d9632 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -100,14 +100,10 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
100 struct callchain_list *chain; 100 struct callchain_list *chain;
101 GtkTreeIter iter, new_parent; 101 GtkTreeIter iter, new_parent;
102 bool need_new_parent; 102 bool need_new_parent;
103 double percent; 103 u64 child_total;
104 u64 hits, child_total;
105 104
106 node = rb_entry(nd, struct callchain_node, rb_node); 105 node = rb_entry(nd, struct callchain_node, rb_node);
107 106
108 hits = callchain_cumul_hits(node);
109 percent = 100.0 * hits / total;
110
111 new_parent = *parent; 107 new_parent = *parent;
112 need_new_parent = !has_single_node && (node->val_nr > 1); 108 need_new_parent = !has_single_node && (node->val_nr > 1);
113 109
@@ -116,7 +112,7 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
116 112
117 gtk_tree_store_append(store, &iter, &new_parent); 113 gtk_tree_store_append(store, &iter, &new_parent);
118 114
119 scnprintf(buf, sizeof(buf), "%5.2f%%", percent); 115 callchain_node__scnprintf_value(node, buf, sizeof(buf), total);
120 gtk_tree_store_set(store, &iter, 0, buf, -1); 116 gtk_tree_store_set(store, &iter, 0, buf, -1);
121 117
122 callchain_list__sym_name(chain, buf, sizeof(buf), false); 118 callchain_list__sym_name(chain, buf, sizeof(buf), false);
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index ea7984932d9a..f4de055cab9b 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -34,10 +34,10 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
34 return ret; 34 return ret;
35} 35}
36 36
37static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, 37static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node,
38 struct callchain_list *chain,
38 int depth, int depth_mask, int period, 39 int depth, int depth_mask, int period,
39 u64 total_samples, u64 hits, 40 u64 total_samples, int left_margin)
40 int left_margin)
41{ 41{
42 int i; 42 int i;
43 size_t ret = 0; 43 size_t ret = 0;
@@ -50,10 +50,9 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
50 else 50 else
51 ret += fprintf(fp, " "); 51 ret += fprintf(fp, " ");
52 if (!period && i == depth - 1) { 52 if (!period && i == depth - 1) {
53 double percent; 53 ret += fprintf(fp, "--");
54 54 ret += callchain_node__fprintf_value(node, fp, total_samples);
55 percent = hits * 100.0 / total_samples; 55 ret += fprintf(fp, "--");
56 ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
57 } else 56 } else
58 ret += fprintf(fp, "%s", " "); 57 ret += fprintf(fp, "%s", " ");
59 } 58 }
@@ -120,10 +119,9 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
120 left_margin); 119 left_margin);
121 i = 0; 120 i = 0;
122 list_for_each_entry(chain, &child->val, list) { 121 list_for_each_entry(chain, &child->val, list) {
123 ret += ipchain__fprintf_graph(fp, chain, depth, 122 ret += ipchain__fprintf_graph(fp, child, chain, depth,
124 new_depth_mask, i++, 123 new_depth_mask, i++,
125 total_samples, 124 total_samples,
126 cumul,
127 left_margin); 125 left_margin);
128 } 126 }
129 127
@@ -143,14 +141,17 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
143 141
144 if (callchain_param.mode == CHAIN_GRAPH_REL && 142 if (callchain_param.mode == CHAIN_GRAPH_REL &&
145 remaining && remaining != total_samples) { 143 remaining && remaining != total_samples) {
144 struct callchain_node rem_node = {
145 .hit = remaining,
146 };
146 147
147 if (!rem_sq_bracket) 148 if (!rem_sq_bracket)
148 return ret; 149 return ret;
149 150
150 new_depth_mask &= ~(1 << (depth - 1)); 151 new_depth_mask &= ~(1 << (depth - 1));
151 ret += ipchain__fprintf_graph(fp, &rem_hits, depth, 152 ret += ipchain__fprintf_graph(fp, &rem_node, &rem_hits, depth,
152 new_depth_mask, 0, total_samples, 153 new_depth_mask, 0, total_samples,
153 remaining, left_margin); 154 left_margin);
154 } 155 }
155 156
156 return ret; 157 return ret;
@@ -243,12 +244,11 @@ static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *tree,
243 struct rb_node *rb_node = rb_first(tree); 244 struct rb_node *rb_node = rb_first(tree);
244 245
245 while (rb_node) { 246 while (rb_node) {
246 double percent;
247
248 chain = rb_entry(rb_node, struct callchain_node, rb_node); 247 chain = rb_entry(rb_node, struct callchain_node, rb_node);
249 percent = chain->hit * 100.0 / total_samples;
250 248
251 ret = percent_color_fprintf(fp, " %6.2f%%\n", percent); 249 ret += fprintf(fp, " ");
250 ret += callchain_node__fprintf_value(chain, fp, total_samples);
251 ret += fprintf(fp, "\n");
252 ret += __callchain__fprintf_flat(fp, chain, total_samples); 252 ret += __callchain__fprintf_flat(fp, chain, total_samples);
253 ret += fprintf(fp, "\n"); 253 ret += fprintf(fp, "\n");
254 if (++entries_printed == callchain_param.print_limit) 254 if (++entries_printed == callchain_param.print_limit)
@@ -295,12 +295,11 @@ static size_t callchain__fprintf_folded(FILE *fp, struct rb_root *tree,
295 struct rb_node *rb_node = rb_first(tree); 295 struct rb_node *rb_node = rb_first(tree);
296 296
297 while (rb_node) { 297 while (rb_node) {
298 double percent;
299 298
300 chain = rb_entry(rb_node, struct callchain_node, rb_node); 299 chain = rb_entry(rb_node, struct callchain_node, rb_node);
301 percent = chain->hit * 100.0 / total_samples;
302 300
303 ret += fprintf(fp, "%.2f%% ", percent); 301 ret += callchain_node__fprintf_value(chain, fp, total_samples);
302 ret += fprintf(fp, " ");
304 ret += __callchain__fprintf_folded(fp, chain); 303 ret += __callchain__fprintf_folded(fp, chain);
305 ret += fprintf(fp, "\n"); 304 ret += fprintf(fp, "\n");
306 if (++entries_printed == callchain_param.print_limit) 305 if (++entries_printed == callchain_param.print_limit)
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 08cb220ba5ea..b948bd068966 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -805,6 +805,35 @@ char *callchain_list__sym_name(struct callchain_list *cl,
805 return bf; 805 return bf;
806} 806}
807 807
808char *callchain_node__scnprintf_value(struct callchain_node *node,
809 char *bf, size_t bfsize, u64 total)
810{
811 double percent = 0.0;
812 u64 period = callchain_cumul_hits(node);
813
814 if (callchain_param.mode == CHAIN_FOLDED)
815 period = node->hit;
816 if (total)
817 percent = period * 100.0 / total;
818
819 scnprintf(bf, bfsize, "%.2f%%", percent);
820 return bf;
821}
822
823int callchain_node__fprintf_value(struct callchain_node *node,
824 FILE *fp, u64 total)
825{
826 double percent = 0.0;
827 u64 period = callchain_cumul_hits(node);
828
829 if (callchain_param.mode == CHAIN_FOLDED)
830 period = node->hit;
831 if (total)
832 percent = period * 100.0 / total;
833
834 return percent_color_fprintf(fp, "%.2f%%", percent);
835}
836
808static void free_callchain_node(struct callchain_node *node) 837static void free_callchain_node(struct callchain_node *node)
809{ 838{
810 struct callchain_list *list, *tmp; 839 struct callchain_list *list, *tmp;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 544d99ac169c..060e636e33ab 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -230,6 +230,10 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
230 230
231char *callchain_list__sym_name(struct callchain_list *cl, 231char *callchain_list__sym_name(struct callchain_list *cl,
232 char *bf, size_t bfsize, bool show_dso); 232 char *bf, size_t bfsize, bool show_dso);
233char *callchain_node__scnprintf_value(struct callchain_node *node,
234 char *bf, size_t bfsize, u64 total);
235int callchain_node__fprintf_value(struct callchain_node *node,
236 FILE *fp, u64 total);
233 237
234void free_callchain(struct callchain_root *root); 238void free_callchain(struct callchain_root *root);
235 239