|
@@ -24,6 +24,11 @@ static char diff__default_sort_order[] = "dso,symbol";
|
|
|
static bool force;
|
|
|
static bool show_displacement;
|
|
|
|
|
|
+struct perf_diff {
|
|
|
+ struct perf_tool tool;
|
|
|
+ struct perf_session *session;
|
|
|
+};
|
|
|
+
|
|
|
static int hists__add_entry(struct hists *self,
|
|
|
struct addr_location *al, u64 period)
|
|
|
{
|
|
@@ -32,12 +37,14 @@ static int hists__add_entry(struct hists *self,
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
-static int diff__process_sample_event(struct perf_tool *tool __used,
|
|
|
+static int diff__process_sample_event(struct perf_tool *tool,
|
|
|
union perf_event *event,
|
|
|
struct perf_sample *sample,
|
|
|
struct perf_evsel *evsel __used,
|
|
|
struct machine *machine)
|
|
|
{
|
|
|
+ struct perf_diff *_diff = container_of(tool, struct perf_diff, tool);
|
|
|
+ struct perf_session *session = _diff->session;
|
|
|
struct addr_location al;
|
|
|
|
|
|
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,
|
|
|
if (al.filtered || al.sym == NULL)
|
|
|
return 0;
|
|
|
|
|
|
- if (hists__add_entry(&evsel->hists, &al, sample->period)) {
|
|
|
+ if (hists__add_entry(&session->hists, &al, sample->period)) {
|
|
|
pr_warning("problem incrementing symbol period, skipping event\n");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- evsel->hists.stats.total_period += sample->period;
|
|
|
+ session->hists.stats.total_period += sample->period;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static struct perf_tool perf_diff = {
|
|
|
- .sample = diff__process_sample_event,
|
|
|
- .mmap = perf_event__process_mmap,
|
|
|
- .comm = perf_event__process_comm,
|
|
|
- .exit = perf_event__process_task,
|
|
|
- .fork = perf_event__process_task,
|
|
|
- .lost = perf_event__process_lost,
|
|
|
- .ordered_samples = true,
|
|
|
- .ordering_requires_timestamps = true,
|
|
|
+static struct perf_diff diff = {
|
|
|
+ .tool = {
|
|
|
+ .sample = diff__process_sample_event,
|
|
|
+ .mmap = perf_event__process_mmap,
|
|
|
+ .comm = perf_event__process_comm,
|
|
|
+ .exit = perf_event__process_task,
|
|
|
+ .fork = perf_event__process_task,
|
|
|
+ .lost = perf_event__process_lost,
|
|
|
+ .ordered_samples = true,
|
|
|
+ .ordering_requires_timestamps = true,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
|
|
@@ -107,12 +116,6 @@ static void hists__resort_entries(struct hists *self)
|
|
|
self->entries = tmp;
|
|
|
}
|
|
|
|
|
|
-static void hists__set_positions(struct hists *self)
|
|
|
-{
|
|
|
- hists__output_resort(self);
|
|
|
- hists__resort_entries(self);
|
|
|
-}
|
|
|
-
|
|
|
static struct hist_entry *hists__find_entry(struct hists *self,
|
|
|
struct hist_entry *he)
|
|
|
{
|
|
@@ -146,30 +149,37 @@ static void hists__match(struct hists *older, struct hists *newer)
|
|
|
static int __cmd_diff(void)
|
|
|
{
|
|
|
int ret, i;
|
|
|
+#define older (session[0])
|
|
|
+#define newer (session[1])
|
|
|
struct perf_session *session[2];
|
|
|
|
|
|
- session[0] = perf_session__new(input_old, O_RDONLY, force, false, &perf_diff);
|
|
|
- session[1] = perf_session__new(input_new, O_RDONLY, force, false, &perf_diff);
|
|
|
+ older = perf_session__new(input_old, O_RDONLY, force, false,
|
|
|
+ &diff.tool);
|
|
|
+ newer = perf_session__new(input_new, O_RDONLY, force, false,
|
|
|
+ &diff.tool);
|
|
|
if (session[0] == NULL || session[1] == NULL)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
for (i = 0; i < 2; ++i) {
|
|
|
- ret = perf_session__process_events(session[i], &perf_diff);
|
|
|
+ diff.session = session[i];
|
|
|
+ ret = perf_session__process_events(session[i], &diff.tool);
|
|
|
if (ret)
|
|
|
goto out_delete;
|
|
|
+ hists__output_resort(&session[i]->hists);
|
|
|
}
|
|
|
|
|
|
- hists__output_resort(&session[1]->hists);
|
|
|
if (show_displacement)
|
|
|
- hists__set_positions(&session[0]->hists);
|
|
|
+ hists__resort_entries(&older->hists);
|
|
|
|
|
|
- hists__match(&session[0]->hists, &session[1]->hists);
|
|
|
- hists__fprintf(&session[1]->hists, &session[0]->hists,
|
|
|
+ hists__match(&older->hists, &newer->hists);
|
|
|
+ hists__fprintf(&newer->hists, &older->hists,
|
|
|
show_displacement, true, 0, 0, stdout);
|
|
|
out_delete:
|
|
|
for (i = 0; i < 2; ++i)
|
|
|
perf_session__delete(session[i]);
|
|
|
return ret;
|
|
|
+#undef older
|
|
|
+#undef newer
|
|
|
}
|
|
|
|
|
|
static const char * const diff_usage[] = {
|