aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-diff.c21
-rw-r--r--tools/perf/ui/hist.c10
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/sort.h27
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
155double perf_diff__compute_delta(struct hist_entry *he) 155double 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
166double perf_diff__compute_ratio(struct hist_entry *he) 166double 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
177s64 perf_diff__compute_wdiff(struct hist_entry *he) 177s64 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
194static int formula_delta(struct hist_entry *he, char *buf, size_t size) 194static 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
208static int formula_ratio(struct hist_entry *he, char *buf, size_t size) 208static 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
220static int formula_wdiff(struct hist_entry *he, char *buf, size_t size) 220static 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
162static double baseline_percent(struct hist_entry *he) 162static 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
249static int hpp__entry_period_baseline(struct perf_hpp *hpp, struct hist_entry *he) 249static 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)
354static int hpp__entry_displ(struct perf_hpp *hpp, 354static 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 {
77struct hist_entry { 77struct 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
109static inline bool hist_entry__has_pairs(struct hist_entry *he)
110{
111 return !list_empty(&he->pairs.node);
112}
113
114static 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
121static 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
108enum sort_type { 127enum sort_type {
109 SORT_PID, 128 SORT_PID,
110 SORT_COMM, 129 SORT_COMM,