aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-diff.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 21:20:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 21:20:11 -0400
commitade0899b298ba2c43bfd6abd8cbc2545944cde0c (patch)
treea448dfb440b3b958b6306bb43620cd5d76f504bf /tools/perf/builtin-diff.c
parent871a0596cb2f51b57dc583d1a7c4be0186582fe7 (diff)
parent95cf59ea72331d0093010543b8951bb43f262cac (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "This tree includes some late late perf items that missed the first round: tools: - Bash auto completion improvements, now we can auto complete the tools long options, tracepoint event names, etc, from Namhyung Kim. - Look up thread using tid instead of pid in 'perf sched'. - Move global variables into a perf_kvm struct, from David Ahern. - Hists refactorings, preparatory for improved 'diff' command, from Jiri Olsa. - Hists refactorings, preparatory for event group viewieng work, from Namhyung Kim. - Remove double negation on optional feature macro definitions, from Namhyung Kim. - Remove several cases of needless global variables, on most builtins. - misc fixes kernel: - sysfs support for IBS on AMD CPUs, from Robert Richter. - Support for an upcoming Intel CPU, the Xeon-Phi / Knights Corner HPC blade PMU, from Vince Weaver. - misc fixes" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (46 commits) perf: Fix perf_cgroup_switch for sw-events perf: Clarify perf_cpu_context::active_pmu usage by renaming it to ::unique_pmu perf/AMD/IBS: Add sysfs support perf hists: Add more helpers for hist entry stat perf hists: Move he->stat.nr_events initialization to a template perf hists: Introduce struct he_stat perf diff: Removing the total_period argument from output code perf tool: Add hpp interface to enable/disable hpp column perf tools: Removing hists pair argument from output path perf hists: Separate overhead and baseline columns perf diff: Refactor diff displacement possition info perf hists: Add struct hists pointer to struct hist_entry perf tools: Complete tracepoint event names perf/x86: Add support for Intel Xeon-Phi Knights Corner PMU perf evlist: Remove some unused methods perf evlist: Introduce add_newtp method perf kvm: Move global variables into a perf_kvm struct perf tools: Convert to BACKTRACE_SUPPORT perf tools: Long option completion support for each subcommands perf tools: Complete long option names of perf command ...
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r--tools/perf/builtin-diff.c68
1 files changed, 49 insertions, 19 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 761f4197a9e2..a0b531c14b97 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -70,8 +70,8 @@ static struct perf_tool tool = {
70 .ordering_requires_timestamps = true, 70 .ordering_requires_timestamps = true,
71}; 71};
72 72
73static void perf_session__insert_hist_entry_by_name(struct rb_root *root, 73static void insert_hist_entry_by_name(struct rb_root *root,
74 struct hist_entry *he) 74 struct hist_entry *he)
75{ 75{
76 struct rb_node **p = &root->rb_node; 76 struct rb_node **p = &root->rb_node;
77 struct rb_node *parent = NULL; 77 struct rb_node *parent = NULL;
@@ -90,7 +90,7 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
90 rb_insert_color(&he->rb_node, root); 90 rb_insert_color(&he->rb_node, root);
91} 91}
92 92
93static void hists__resort_entries(struct hists *self) 93static void hists__name_resort(struct hists *self, bool sort)
94{ 94{
95 unsigned long position = 1; 95 unsigned long position = 1;
96 struct rb_root tmp = RB_ROOT; 96 struct rb_root tmp = RB_ROOT;
@@ -100,12 +100,16 @@ static void hists__resort_entries(struct hists *self)
100 struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node); 100 struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node);
101 101
102 next = rb_next(&n->rb_node); 102 next = rb_next(&n->rb_node);
103 rb_erase(&n->rb_node, &self->entries);
104 n->position = position++; 103 n->position = position++;
105 perf_session__insert_hist_entry_by_name(&tmp, n); 104
105 if (sort) {
106 rb_erase(&n->rb_node, &self->entries);
107 insert_hist_entry_by_name(&tmp, n);
108 }
106 } 109 }
107 110
108 self->entries = tmp; 111 if (sort)
112 self->entries = tmp;
109} 113}
110 114
111static struct hist_entry *hists__find_entry(struct hists *self, 115static struct hist_entry *hists__find_entry(struct hists *self,
@@ -121,7 +125,7 @@ static struct hist_entry *hists__find_entry(struct hists *self,
121 n = n->rb_left; 125 n = n->rb_left;
122 else if (cmp > 0) 126 else if (cmp > 0)
123 n = n->rb_right; 127 n = n->rb_right;
124 else 128 else
125 return iter; 129 return iter;
126 } 130 }
127 131
@@ -150,6 +154,24 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
150 return NULL; 154 return NULL;
151} 155}
152 156
157static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name)
158{
159 struct perf_evsel *evsel;
160
161 list_for_each_entry(evsel, &evlist->entries, node) {
162 struct hists *hists = &evsel->hists;
163
164 hists__output_resort(hists);
165
166 /*
167 * The hists__name_resort only sets possition
168 * if name is false.
169 */
170 if (name || ((!name) && show_displacement))
171 hists__name_resort(hists, name);
172 }
173}
174
153static int __cmd_diff(void) 175static int __cmd_diff(void)
154{ 176{
155 int ret, i; 177 int ret, i;
@@ -176,15 +198,8 @@ static int __cmd_diff(void)
176 evlist_old = older->evlist; 198 evlist_old = older->evlist;
177 evlist_new = newer->evlist; 199 evlist_new = newer->evlist;
178 200
179 list_for_each_entry(evsel, &evlist_new->entries, node) 201 perf_evlist__resort_hists(evlist_old, true);
180 hists__output_resort(&evsel->hists); 202 perf_evlist__resort_hists(evlist_new, false);
181
182 list_for_each_entry(evsel, &evlist_old->entries, node) {
183 hists__output_resort(&evsel->hists);
184
185 if (show_displacement)
186 hists__resort_entries(&evsel->hists);
187 }
188 203
189 list_for_each_entry(evsel, &evlist_new->entries, node) { 204 list_for_each_entry(evsel, &evlist_new->entries, node) {
190 struct perf_evsel *evsel_old; 205 struct perf_evsel *evsel_old;
@@ -199,8 +214,7 @@ static int __cmd_diff(void)
199 first = false; 214 first = false;
200 215
201 hists__match(&evsel_old->hists, &evsel->hists); 216 hists__match(&evsel_old->hists, &evsel->hists);
202 hists__fprintf(&evsel->hists, &evsel_old->hists, 217 hists__fprintf(&evsel->hists, true, 0, 0, stdout);
203 show_displacement, true, 0, 0, stdout);
204 } 218 }
205 219
206out_delete: 220out_delete:
@@ -242,6 +256,21 @@ static const struct option options[] = {
242 OPT_END() 256 OPT_END()
243}; 257};
244 258
259static void ui_init(void)
260{
261 perf_hpp__init();
262
263 /* No overhead column. */
264 perf_hpp__column_enable(PERF_HPP__OVERHEAD, false);
265
266 /* Display baseline/delta/displacement columns. */
267 perf_hpp__column_enable(PERF_HPP__BASELINE, true);
268 perf_hpp__column_enable(PERF_HPP__DELTA, true);
269
270 if (show_displacement)
271 perf_hpp__column_enable(PERF_HPP__DISPL, true);
272}
273
245int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) 274int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
246{ 275{
247 sort_order = diff__default_sort_order; 276 sort_order = diff__default_sort_order;
@@ -264,7 +293,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
264 if (symbol__init() < 0) 293 if (symbol__init() < 0)
265 return -1; 294 return -1;
266 295
267 perf_hpp__init(true, show_displacement); 296 ui_init();
297
268 setup_sorting(diff_usage, options); 298 setup_sorting(diff_usage, options);
269 setup_pager(); 299 setup_pager();
270 300