diff options
-rw-r--r-- | tools/perf/builtin-diff.c | 21 | ||||
-rw-r--r-- | tools/perf/ui/hist.c | 10 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 2 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 27 |
4 files changed, 42 insertions, 18 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 380683de1df3..8a9db38e562f 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -154,7 +154,7 @@ static double get_period_percent(struct hist_entry *he, u64 period) | |||
154 | 154 | ||
155 | double perf_diff__compute_delta(struct hist_entry *he) | 155 | double perf_diff__compute_delta(struct hist_entry *he) |
156 | { | 156 | { |
157 | struct hist_entry *pair = he->pair; | 157 | struct hist_entry *pair = hist_entry__next_pair(he); |
158 | double new_percent = get_period_percent(he, he->stat.period); | 158 | double new_percent = get_period_percent(he, he->stat.period); |
159 | double old_percent = pair ? get_period_percent(pair, pair->stat.period) : 0.0; | 159 | double old_percent = pair ? get_period_percent(pair, pair->stat.period) : 0.0; |
160 | 160 | ||
@@ -165,7 +165,7 @@ double perf_diff__compute_delta(struct hist_entry *he) | |||
165 | 165 | ||
166 | double perf_diff__compute_ratio(struct hist_entry *he) | 166 | double perf_diff__compute_ratio(struct hist_entry *he) |
167 | { | 167 | { |
168 | struct hist_entry *pair = he->pair; | 168 | struct hist_entry *pair = hist_entry__next_pair(he); |
169 | double new_period = he->stat.period; | 169 | double new_period = he->stat.period; |
170 | double old_period = pair ? pair->stat.period : 0; | 170 | double old_period = pair ? pair->stat.period : 0; |
171 | 171 | ||
@@ -176,7 +176,7 @@ double perf_diff__compute_ratio(struct hist_entry *he) | |||
176 | 176 | ||
177 | s64 perf_diff__compute_wdiff(struct hist_entry *he) | 177 | s64 perf_diff__compute_wdiff(struct hist_entry *he) |
178 | { | 178 | { |
179 | struct hist_entry *pair = he->pair; | 179 | struct hist_entry *pair = hist_entry__next_pair(he); |
180 | u64 new_period = he->stat.period; | 180 | u64 new_period = he->stat.period; |
181 | u64 old_period = pair ? pair->stat.period : 0; | 181 | u64 old_period = pair ? pair->stat.period : 0; |
182 | 182 | ||
@@ -193,7 +193,7 @@ s64 perf_diff__compute_wdiff(struct hist_entry *he) | |||
193 | 193 | ||
194 | static int formula_delta(struct hist_entry *he, char *buf, size_t size) | 194 | static int formula_delta(struct hist_entry *he, char *buf, size_t size) |
195 | { | 195 | { |
196 | struct hist_entry *pair = he->pair; | 196 | struct hist_entry *pair = hist_entry__next_pair(he); |
197 | 197 | ||
198 | if (!pair) | 198 | if (!pair) |
199 | return -1; | 199 | return -1; |
@@ -207,7 +207,7 @@ static int formula_delta(struct hist_entry *he, char *buf, size_t size) | |||
207 | 207 | ||
208 | static int formula_ratio(struct hist_entry *he, char *buf, size_t size) | 208 | static int formula_ratio(struct hist_entry *he, char *buf, size_t size) |
209 | { | 209 | { |
210 | struct hist_entry *pair = he->pair; | 210 | struct hist_entry *pair = hist_entry__next_pair(he); |
211 | double new_period = he->stat.period; | 211 | double new_period = he->stat.period; |
212 | double old_period = pair ? pair->stat.period : 0; | 212 | double old_period = pair ? pair->stat.period : 0; |
213 | 213 | ||
@@ -219,7 +219,7 @@ static int formula_ratio(struct hist_entry *he, char *buf, size_t size) | |||
219 | 219 | ||
220 | static int formula_wdiff(struct hist_entry *he, char *buf, size_t size) | 220 | static int formula_wdiff(struct hist_entry *he, char *buf, size_t size) |
221 | { | 221 | { |
222 | struct hist_entry *pair = he->pair; | 222 | struct hist_entry *pair = hist_entry__next_pair(he); |
223 | u64 new_period = he->stat.period; | 223 | u64 new_period = he->stat.period; |
224 | u64 old_period = pair ? pair->stat.period : 0; | 224 | u64 old_period = pair ? pair->stat.period : 0; |
225 | 225 | ||
@@ -359,8 +359,11 @@ static void hists__match(struct hists *older, struct hists *newer) | |||
359 | struct rb_node *nd; | 359 | struct rb_node *nd; |
360 | 360 | ||
361 | for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) { | 361 | for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) { |
362 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); | 362 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node), |
363 | pos->pair = hists__find_entry(older, pos); | 363 | *pair = hists__find_entry(older, pos); |
364 | |||
365 | if (pair) | ||
366 | hist__entry_add_pair(pos, pair); | ||
364 | } | 367 | } |
365 | } | 368 | } |
366 | 369 | ||
@@ -402,7 +405,7 @@ static void hists__baseline_only(struct hists *hists) | |||
402 | struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); | 405 | struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); |
403 | 406 | ||
404 | next = rb_next(&he->rb_node); | 407 | next = rb_next(&he->rb_node); |
405 | if (!he->pair) { | 408 | if (!hist_entry__next_pair(he)) { |
406 | rb_erase(&he->rb_node, &hists->entries); | 409 | rb_erase(&he->rb_node, &hists->entries); |
407 | hist_entry__free(he); | 410 | hist_entry__free(he); |
408 | } | 411 | } |
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 4f5f4756faac..aa84130024d5 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c | |||
@@ -161,7 +161,7 @@ static int hpp__width_baseline(struct perf_hpp *hpp __maybe_unused) | |||
161 | 161 | ||
162 | static double baseline_percent(struct hist_entry *he) | 162 | static double baseline_percent(struct hist_entry *he) |
163 | { | 163 | { |
164 | struct hist_entry *pair = he->pair; | 164 | struct hist_entry *pair = hist_entry__next_pair(he); |
165 | struct hists *pair_hists = pair ? pair->hists : NULL; | 165 | struct hists *pair_hists = pair ? pair->hists : NULL; |
166 | double percent = 0.0; | 166 | double percent = 0.0; |
167 | 167 | ||
@@ -179,7 +179,7 @@ static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he) | |||
179 | { | 179 | { |
180 | double percent = baseline_percent(he); | 180 | double percent = baseline_percent(he); |
181 | 181 | ||
182 | if (he->pair) | 182 | if (hist_entry__has_pairs(he)) |
183 | return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); | 183 | return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); |
184 | else | 184 | else |
185 | return scnprintf(hpp->buf, hpp->size, " "); | 185 | return scnprintf(hpp->buf, hpp->size, " "); |
@@ -190,7 +190,7 @@ static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he) | |||
190 | double percent = baseline_percent(he); | 190 | double percent = baseline_percent(he); |
191 | const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%"; | 191 | const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%"; |
192 | 192 | ||
193 | if (he->pair || symbol_conf.field_sep) | 193 | if (hist_entry__has_pairs(he) || symbol_conf.field_sep) |
194 | return scnprintf(hpp->buf, hpp->size, fmt, percent); | 194 | return scnprintf(hpp->buf, hpp->size, fmt, percent); |
195 | else | 195 | else |
196 | return scnprintf(hpp->buf, hpp->size, " "); | 196 | return scnprintf(hpp->buf, hpp->size, " "); |
@@ -248,7 +248,7 @@ static int hpp__width_period_baseline(struct perf_hpp *hpp __maybe_unused) | |||
248 | 248 | ||
249 | static int hpp__entry_period_baseline(struct perf_hpp *hpp, struct hist_entry *he) | 249 | static int hpp__entry_period_baseline(struct perf_hpp *hpp, struct hist_entry *he) |
250 | { | 250 | { |
251 | struct hist_entry *pair = he->pair; | 251 | struct hist_entry *pair = hist_entry__next_pair(he); |
252 | u64 period = pair ? pair->stat.period : 0; | 252 | u64 period = pair ? pair->stat.period : 0; |
253 | const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64; | 253 | const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64; |
254 | 254 | ||
@@ -354,7 +354,7 @@ static int hpp__width_displ(struct perf_hpp *hpp __maybe_unused) | |||
354 | static int hpp__entry_displ(struct perf_hpp *hpp, | 354 | static int hpp__entry_displ(struct perf_hpp *hpp, |
355 | struct hist_entry *he) | 355 | struct hist_entry *he) |
356 | { | 356 | { |
357 | struct hist_entry *pair = he->pair; | 357 | struct hist_entry *pair = hist_entry__next_pair(he); |
358 | long displacement = pair ? pair->position - he->position : 0; | 358 | long displacement = pair ? pair->position - he->position : 0; |
359 | const char *fmt = symbol_conf.field_sep ? "%s" : "%6.6s"; | 359 | const char *fmt = symbol_conf.field_sep ? "%s" : "%6.6s"; |
360 | char buf[32] = " "; | 360 | char buf[32] = " "; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index a1b823f8c17f..f42de79d2e6b 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -244,6 +244,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) | |||
244 | he->ms.map->referenced = true; | 244 | he->ms.map->referenced = true; |
245 | if (symbol_conf.use_callchain) | 245 | if (symbol_conf.use_callchain) |
246 | callchain_init(he->callchain); | 246 | callchain_init(he->callchain); |
247 | |||
248 | INIT_LIST_HEAD(&he->pairs.node); | ||
247 | } | 249 | } |
248 | 250 | ||
249 | return he; | 251 | return he; |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 13761d83a5a0..b4e8c3ba559d 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -77,6 +77,10 @@ struct hist_entry_diff { | |||
77 | struct hist_entry { | 77 | struct hist_entry { |
78 | struct rb_node rb_node_in; | 78 | struct rb_node rb_node_in; |
79 | struct rb_node rb_node; | 79 | struct rb_node rb_node; |
80 | union { | ||
81 | struct list_head node; | ||
82 | struct list_head head; | ||
83 | } pairs; | ||
80 | struct he_stat stat; | 84 | struct he_stat stat; |
81 | struct map_symbol ms; | 85 | struct map_symbol ms; |
82 | struct thread *thread; | 86 | struct thread *thread; |
@@ -96,15 +100,30 @@ struct hist_entry { | |||
96 | char *srcline; | 100 | char *srcline; |
97 | struct symbol *parent; | 101 | struct symbol *parent; |
98 | unsigned long position; | 102 | unsigned long position; |
99 | union { | 103 | struct rb_root sorted_chain; |
100 | struct hist_entry *pair; | ||
101 | struct rb_root sorted_chain; | ||
102 | }; | ||
103 | struct branch_info *branch_info; | 104 | struct branch_info *branch_info; |
104 | struct hists *hists; | 105 | struct hists *hists; |
105 | struct callchain_root callchain[0]; | 106 | struct callchain_root callchain[0]; |
106 | }; | 107 | }; |
107 | 108 | ||
109 | static inline bool hist_entry__has_pairs(struct hist_entry *he) | ||
110 | { | ||
111 | return !list_empty(&he->pairs.node); | ||
112 | } | ||
113 | |||
114 | static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he) | ||
115 | { | ||
116 | if (hist_entry__has_pairs(he)) | ||
117 | return list_entry(he->pairs.node.next, struct hist_entry, pairs.node); | ||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | static inline void hist__entry_add_pair(struct hist_entry *he, | ||
122 | struct hist_entry *pair) | ||
123 | { | ||
124 | list_add_tail(&he->pairs.head, &pair->pairs.node); | ||
125 | } | ||
126 | |||
108 | enum sort_type { | 127 | enum sort_type { |
109 | SORT_PID, | 128 | SORT_PID, |
110 | SORT_COMM, | 129 | SORT_COMM, |