aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo2012-10-25 11:42:45 -0500
committerArnaldo Carvalho de Melo2012-11-08 14:43:09 -0600
commitb821c7325354c589ccc9611cf9e6b0d7490ed6a6 (patch)
tree103deb4210a3187c52597def760435502cdc907e /tools/perf
parentff6f7778a66edc033044a6baa2459ce79519e571 (diff)
downloadkernel-omap-b821c7325354c589ccc9611cf9e6b0d7490ed6a6.tar.gz
kernel-omap-b821c7325354c589ccc9611cf9e6b0d7490ed6a6.tar.xz
kernel-omap-b821c7325354c589ccc9611cf9e6b0d7490ed6a6.zip
perf diff: Start moving to support matching more than two hists
We want to match more than two hists, so that we can match more than two perf.data files and moreover, match hist_entries (buckets) in multiple events in a group. So the "baseline"/"leader" will instead of a ->pair pointer, use a list_head, that will link to the pairs and hists__match use it. Following that perf_evlist__link will link the hists in its evsel groups. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-2kbmzepoi544ygj9godseqpv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-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,