Skip to content

Commit

Permalink
perf session: Cache sample objects
Browse files Browse the repository at this point in the history
When the sample queue is flushed we free the sample reference objects. Though
we need to malloc new objects when we process further. Stop the malloc/free
orgy and cache the already allocated object for resuage. Only allocate when
the cache is empty.

Performance gain: ~ 10%

Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20101130163820.338488630@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Thomas Gleixner authored and Arnaldo Carvalho de Melo committed Nov 30, 2010
1 parent fe17420 commit 020bb75
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
30 changes: 26 additions & 4 deletions tools/perf/util/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
self->machines = RB_ROOT;
self->repipe = repipe;
INIT_LIST_HEAD(&self->ordered_samples.samples);
INIT_LIST_HEAD(&self->ordered_samples.sample_cache);
machine__init(&self->host_machine, "", HOST_KERNEL_ID);

if (mode == O_RDONLY) {
Expand Down Expand Up @@ -398,6 +399,19 @@ struct sample_queue {
struct list_head list;
};

static void perf_session_free_sample_buffers(struct perf_session *session)
{
struct ordered_samples *os = &session->ordered_samples;

while (!list_empty(&os->sample_cache)) {
struct sample_queue *sq;

sq = list_entry(os->sample_cache.next, struct sample_queue, list);
list_del(&sq->list);
free(sq);
}
}

static void flush_sample_queue(struct perf_session *s,
struct perf_event_ops *ops)
{
Expand All @@ -418,7 +432,7 @@ static void flush_sample_queue(struct perf_session *s,

os->last_flush = iter->timestamp;
list_del(&iter->list);
free(iter);
list_add(&iter->list, &os->sample_cache);
}

if (list_empty(head)) {
Expand Down Expand Up @@ -527,6 +541,7 @@ static void __queue_sample_event(struct sample_queue *new,
static int queue_sample_event(event_t *event, struct sample_data *data,
struct perf_session *s)
{
struct list_head *sc = &s->ordered_samples.sample_cache;
u64 timestamp = data->time;
struct sample_queue *new;

Expand All @@ -535,9 +550,14 @@ static int queue_sample_event(event_t *event, struct sample_data *data,
return -EINVAL;
}

new = malloc(sizeof(*new));
if (!new)
return -ENOMEM;
if (!list_empty(sc)) {
new = list_entry(sc->next, struct sample_queue, list);
list_del(&new->list);
} else {
new = malloc(sizeof(*new));
if (!new)
return -ENOMEM;
}

new->timestamp = timestamp;
new->event = event;
Expand Down Expand Up @@ -730,6 +750,7 @@ static int __perf_session__process_pipe_events(struct perf_session *self,
done:
err = 0;
out_err:
perf_session_free_sample_buffers(self);
return err;
}

Expand Down Expand Up @@ -862,6 +883,7 @@ int __perf_session__process_events(struct perf_session *session,
session->hists.stats.nr_unknown_events);
}

perf_session_free_sample_buffers(session);
return err;
}

Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct ordered_samples {
u64 next_flush;
u64 max_timestamp;
struct list_head samples;
struct list_head sample_cache;
struct sample_queue *last_sample;
};

Expand Down

0 comments on commit 020bb75

Please sign in to comment.