Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 323777
b: refs/heads/master
c: 863e451
h: refs/heads/master
i:
  323775: a220519
v: v3
  • Loading branch information
Jiri Olsa authored and Arnaldo Carvalho de Melo committed Sep 8, 2012
1 parent 7244d8f commit 5095153
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 36 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 67ed939c9eb029c28057eb75de456a9d0e899fd4
refs/heads/master: 863e451f69ddf255e877567e325298edd3b21519
3 changes: 3 additions & 0 deletions trunk/tools/perf/Documentation/perf-diff.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ captured via perf record.

If no parameters are passed it will assume perf.data.old and perf.data.

The differential profile is displayed only for events matching both
specified perf.data files.

OPTIONS
-------
-M::
Expand Down
93 changes: 61 additions & 32 deletions trunk/tools/perf/builtin-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "util/event.h"
#include "util/hist.h"
#include "util/evsel.h"
#include "util/evlist.h"
#include "util/session.h"
#include "util/tool.h"
#include "util/sort.h"
Expand All @@ -24,11 +25,6 @@ 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)
{
Expand All @@ -37,14 +33,12 @@ static int hists__add_entry(struct hists *self,
return -ENOMEM;
}

static int diff__process_sample_event(struct perf_tool *tool,
static int diff__process_sample_event(struct perf_tool *tool __used,
union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel __used,
struct perf_evsel *evsel,
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) {
Expand All @@ -56,26 +50,24 @@ static int diff__process_sample_event(struct perf_tool *tool,
if (al.filtered || al.sym == NULL)
return 0;

if (hists__add_entry(&session->hists, &al, sample->period)) {
if (hists__add_entry(&evsel->hists, &al, sample->period)) {
pr_warning("problem incrementing symbol period, skipping event\n");
return -1;
}

session->hists.stats.total_period += sample->period;
evsel->hists.stats.total_period += sample->period;
return 0;
}

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 struct perf_tool 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,
Expand Down Expand Up @@ -146,34 +138,71 @@ static void hists__match(struct hists *older, struct hists *newer)
}
}

static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
struct perf_evlist *evlist)
{
struct perf_evsel *e;

list_for_each_entry(e, &evlist->entries, node)
if (perf_evsel__match2(evsel, e))
return e;

return NULL;
}

static int __cmd_diff(void)
{
int ret, i;
#define older (session[0])
#define newer (session[1])
struct perf_session *session[2];
struct perf_evlist *evlist_new, *evlist_old;
struct perf_evsel *evsel;
bool first = true;

older = perf_session__new(input_old, O_RDONLY, force, false,
&diff.tool);
&tool);
newer = perf_session__new(input_new, O_RDONLY, force, false,
&diff.tool);
&tool);
if (session[0] == NULL || session[1] == NULL)
return -ENOMEM;

for (i = 0; i < 2; ++i) {
diff.session = session[i];
ret = perf_session__process_events(session[i], &diff.tool);
ret = perf_session__process_events(session[i], &tool);
if (ret)
goto out_delete;
hists__output_resort(&session[i]->hists);
}

if (show_displacement)
hists__resort_entries(&older->hists);
evlist_old = older->evlist;
evlist_new = newer->evlist;

list_for_each_entry(evsel, &evlist_new->entries, node)
hists__output_resort(&evsel->hists);

list_for_each_entry(evsel, &evlist_old->entries, node) {
hists__output_resort(&evsel->hists);

if (show_displacement)
hists__resort_entries(&evsel->hists);
}

list_for_each_entry(evsel, &evlist_new->entries, node) {
struct perf_evsel *evsel_old;

evsel_old = evsel_match(evsel, evlist_old);
if (!evsel_old)
continue;

fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
perf_evsel__name(evsel));

first = false;

hists__match(&evsel_old->hists, &evsel->hists);
hists__fprintf(&evsel->hists, &evsel_old->hists,
show_displacement, true, 0, 0, stdout);
}

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]);
Expand Down
7 changes: 7 additions & 0 deletions trunk/tools/perf/util/evsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads);
(evsel->attr.type == PERF_TYPE_##t && \
evsel->attr.config == PERF_COUNT_##c)

static inline bool perf_evsel__match2(struct perf_evsel *e1,
struct perf_evsel *e2)
{
return (e1->attr.type == e2->attr.type) &&
(e1->attr.config == e2->attr.config);
}

int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
int cpu, int thread, bool scale);

Expand Down
4 changes: 1 addition & 3 deletions trunk/tools/perf/util/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ struct perf_session {
struct pevent *pevent;
/*
* FIXME: Need to split this up further, we need global
* stats + per event stats. 'perf diff' also needs
* to properly support multiple events in a single
* perf.data file.
* stats + per event stats.
*/
struct hists hists;
int fd;
Expand Down

0 comments on commit 5095153

Please sign in to comment.