aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r--tools/perf/builtin-diff.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 4f19513d7dda..d29d350fb2b7 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -24,6 +24,11 @@ static char diff__default_sort_order[] = "dso,symbol";
24static bool force; 24static bool force;
25static bool show_displacement; 25static bool show_displacement;
26 26
27struct perf_diff {
28 struct perf_tool tool;
29 struct perf_session *session;
30};
31
27static int hists__add_entry(struct hists *self, 32static int hists__add_entry(struct hists *self,
28 struct addr_location *al, u64 period) 33 struct addr_location *al, u64 period)
29{ 34{
@@ -32,12 +37,14 @@ static int hists__add_entry(struct hists *self,
32 return -ENOMEM; 37 return -ENOMEM;
33} 38}
34 39
35static int diff__process_sample_event(struct perf_tool *tool __used, 40static int diff__process_sample_event(struct perf_tool *tool,
36 union perf_event *event, 41 union perf_event *event,
37 struct perf_sample *sample, 42 struct perf_sample *sample,
38 struct perf_evsel *evsel __used, 43 struct perf_evsel *evsel __used,
39 struct machine *machine) 44 struct machine *machine)
40{ 45{
46 struct perf_diff *_diff = container_of(tool, struct perf_diff, tool);
47 struct perf_session *session = _diff->session;
41 struct addr_location al; 48 struct addr_location al;
42 49
43 if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { 50 if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) {
@@ -49,24 +56,26 @@ static int diff__process_sample_event(struct perf_tool *tool __used,
49 if (al.filtered || al.sym == NULL) 56 if (al.filtered || al.sym == NULL)
50 return 0; 57 return 0;
51 58
52 if (hists__add_entry(&evsel->hists, &al, sample->period)) { 59 if (hists__add_entry(&session->hists, &al, sample->period)) {
53 pr_warning("problem incrementing symbol period, skipping event\n"); 60 pr_warning("problem incrementing symbol period, skipping event\n");
54 return -1; 61 return -1;
55 } 62 }
56 63
57 evsel->hists.stats.total_period += sample->period; 64 session->hists.stats.total_period += sample->period;
58 return 0; 65 return 0;
59} 66}
60 67
61static struct perf_tool perf_diff = { 68static struct perf_diff diff = {
62 .sample = diff__process_sample_event, 69 .tool = {
63 .mmap = perf_event__process_mmap, 70 .sample = diff__process_sample_event,
64 .comm = perf_event__process_comm, 71 .mmap = perf_event__process_mmap,
65 .exit = perf_event__process_task, 72 .comm = perf_event__process_comm,
66 .fork = perf_event__process_task, 73 .exit = perf_event__process_task,
67 .lost = perf_event__process_lost, 74 .fork = perf_event__process_task,
68 .ordered_samples = true, 75 .lost = perf_event__process_lost,
69 .ordering_requires_timestamps = true, 76 .ordered_samples = true,
77 .ordering_requires_timestamps = true,
78 },
70}; 79};
71 80
72static void perf_session__insert_hist_entry_by_name(struct rb_root *root, 81static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
@@ -107,12 +116,6 @@ static void hists__resort_entries(struct hists *self)
107 self->entries = tmp; 116 self->entries = tmp;
108} 117}
109 118
110static void hists__set_positions(struct hists *self)
111{
112 hists__output_resort(self);
113 hists__resort_entries(self);
114}
115
116static struct hist_entry *hists__find_entry(struct hists *self, 119static struct hist_entry *hists__find_entry(struct hists *self,
117 struct hist_entry *he) 120 struct hist_entry *he)
118{ 121{
@@ -146,30 +149,37 @@ static void hists__match(struct hists *older, struct hists *newer)
146static int __cmd_diff(void) 149static int __cmd_diff(void)
147{ 150{
148 int ret, i; 151 int ret, i;
152#define older (session[0])
153#define newer (session[1])
149 struct perf_session *session[2]; 154 struct perf_session *session[2];
150 155
151 session[0] = perf_session__new(input_old, O_RDONLY, force, false, &perf_diff); 156 older = perf_session__new(input_old, O_RDONLY, force, false,
152 session[1] = perf_session__new(input_new, O_RDONLY, force, false, &perf_diff); 157 &diff.tool);
158 newer = perf_session__new(input_new, O_RDONLY, force, false,
159 &diff.tool);
153 if (session[0] == NULL || session[1] == NULL) 160 if (session[0] == NULL || session[1] == NULL)
154 return -ENOMEM; 161 return -ENOMEM;
155 162
156 for (i = 0; i < 2; ++i) { 163 for (i = 0; i < 2; ++i) {
157 ret = perf_session__process_events(session[i], &perf_diff); 164 diff.session = session[i];
165 ret = perf_session__process_events(session[i], &diff.tool);
158 if (ret) 166 if (ret)
159 goto out_delete; 167 goto out_delete;
168 hists__output_resort(&session[i]->hists);
160 } 169 }
161 170
162 hists__output_resort(&session[1]->hists);
163 if (show_displacement) 171 if (show_displacement)
164 hists__set_positions(&session[0]->hists); 172 hists__resort_entries(&older->hists);
165 173
166 hists__match(&session[0]->hists, &session[1]->hists); 174 hists__match(&older->hists, &newer->hists);
167 hists__fprintf(&session[1]->hists, &session[0]->hists, 175 hists__fprintf(&newer->hists, &older->hists,
168 show_displacement, true, 0, 0, stdout); 176 show_displacement, true, 0, 0, stdout);
169out_delete: 177out_delete:
170 for (i = 0; i < 2; ++i) 178 for (i = 0; i < 2; ++i)
171 perf_session__delete(session[i]); 179 perf_session__delete(session[i]);
172 return ret; 180 return ret;
181#undef older
182#undef newer
173} 183}
174 184
175static const char * const diff_usage[] = { 185static const char * const diff_usage[] = {