diff options
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 8 | ||||
-rw-r--r-- | tools/perf/ui/gtk/hists.c | 8 | ||||
-rw-r--r-- | tools/perf/ui/stdio/hist.c | 35 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 29 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 4 |
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 | ||
37 | static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, | 37 | static 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 | ||
808 | char *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 | |||
823 | int 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 | |||
808 | static void free_callchain_node(struct callchain_node *node) | 837 | static 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 | ||
231 | char *callchain_list__sym_name(struct callchain_list *cl, | 231 | char *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); |
233 | char *callchain_node__scnprintf_value(struct callchain_node *node, | ||
234 | char *bf, size_t bfsize, u64 total); | ||
235 | int callchain_node__fprintf_value(struct callchain_node *node, | ||
236 | FILE *fp, u64 total); | ||
233 | 237 | ||
234 | void free_callchain(struct callchain_root *root); | 238 | void free_callchain(struct callchain_root *root); |
235 | 239 | ||