diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-11-30 12:49:53 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-11-30 17:04:18 -0500 |
commit | 020bb75a6deeca5ebeae531dc7378c157affc8fd (patch) | |
tree | 1e103a173a5454adee9235c52558eef22fc24214 /tools/perf/util | |
parent | fe17420784a6d3602e98f798731369fa05936cbe (diff) |
perf session: Cache sample objects
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>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/session.c | 30 | ||||
-rw-r--r-- | tools/perf/util/session.h | 1 |
2 files changed, 27 insertions, 4 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c98958314102..9fef587ff11f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -113,6 +113,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc | |||
113 | self->machines = RB_ROOT; | 113 | self->machines = RB_ROOT; |
114 | self->repipe = repipe; | 114 | self->repipe = repipe; |
115 | INIT_LIST_HEAD(&self->ordered_samples.samples); | 115 | INIT_LIST_HEAD(&self->ordered_samples.samples); |
116 | INIT_LIST_HEAD(&self->ordered_samples.sample_cache); | ||
116 | machine__init(&self->host_machine, "", HOST_KERNEL_ID); | 117 | machine__init(&self->host_machine, "", HOST_KERNEL_ID); |
117 | 118 | ||
118 | if (mode == O_RDONLY) { | 119 | if (mode == O_RDONLY) { |
@@ -398,6 +399,19 @@ struct sample_queue { | |||
398 | struct list_head list; | 399 | struct list_head list; |
399 | }; | 400 | }; |
400 | 401 | ||
402 | static void perf_session_free_sample_buffers(struct perf_session *session) | ||
403 | { | ||
404 | struct ordered_samples *os = &session->ordered_samples; | ||
405 | |||
406 | while (!list_empty(&os->sample_cache)) { | ||
407 | struct sample_queue *sq; | ||
408 | |||
409 | sq = list_entry(os->sample_cache.next, struct sample_queue, list); | ||
410 | list_del(&sq->list); | ||
411 | free(sq); | ||
412 | } | ||
413 | } | ||
414 | |||
401 | static void flush_sample_queue(struct perf_session *s, | 415 | static void flush_sample_queue(struct perf_session *s, |
402 | struct perf_event_ops *ops) | 416 | struct perf_event_ops *ops) |
403 | { | 417 | { |
@@ -418,7 +432,7 @@ static void flush_sample_queue(struct perf_session *s, | |||
418 | 432 | ||
419 | os->last_flush = iter->timestamp; | 433 | os->last_flush = iter->timestamp; |
420 | list_del(&iter->list); | 434 | list_del(&iter->list); |
421 | free(iter); | 435 | list_add(&iter->list, &os->sample_cache); |
422 | } | 436 | } |
423 | 437 | ||
424 | if (list_empty(head)) { | 438 | if (list_empty(head)) { |
@@ -527,6 +541,7 @@ static void __queue_sample_event(struct sample_queue *new, | |||
527 | static int queue_sample_event(event_t *event, struct sample_data *data, | 541 | static int queue_sample_event(event_t *event, struct sample_data *data, |
528 | struct perf_session *s) | 542 | struct perf_session *s) |
529 | { | 543 | { |
544 | struct list_head *sc = &s->ordered_samples.sample_cache; | ||
530 | u64 timestamp = data->time; | 545 | u64 timestamp = data->time; |
531 | struct sample_queue *new; | 546 | struct sample_queue *new; |
532 | 547 | ||
@@ -535,9 +550,14 @@ static int queue_sample_event(event_t *event, struct sample_data *data, | |||
535 | return -EINVAL; | 550 | return -EINVAL; |
536 | } | 551 | } |
537 | 552 | ||
538 | new = malloc(sizeof(*new)); | 553 | if (!list_empty(sc)) { |
539 | if (!new) | 554 | new = list_entry(sc->next, struct sample_queue, list); |
540 | return -ENOMEM; | 555 | list_del(&new->list); |
556 | } else { | ||
557 | new = malloc(sizeof(*new)); | ||
558 | if (!new) | ||
559 | return -ENOMEM; | ||
560 | } | ||
541 | 561 | ||
542 | new->timestamp = timestamp; | 562 | new->timestamp = timestamp; |
543 | new->event = event; | 563 | new->event = event; |
@@ -730,6 +750,7 @@ more: | |||
730 | done: | 750 | done: |
731 | err = 0; | 751 | err = 0; |
732 | out_err: | 752 | out_err: |
753 | perf_session_free_sample_buffers(self); | ||
733 | return err; | 754 | return err; |
734 | } | 755 | } |
735 | 756 | ||
@@ -862,6 +883,7 @@ out_err: | |||
862 | session->hists.stats.nr_unknown_events); | 883 | session->hists.stats.nr_unknown_events); |
863 | } | 884 | } |
864 | 885 | ||
886 | perf_session_free_sample_buffers(session); | ||
865 | return err; | 887 | return err; |
866 | } | 888 | } |
867 | 889 | ||
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index a00f32ed1c79..e4a7ff2ba8d5 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -18,6 +18,7 @@ struct ordered_samples { | |||
18 | u64 next_flush; | 18 | u64 next_flush; |
19 | u64 max_timestamp; | 19 | u64 max_timestamp; |
20 | struct list_head samples; | 20 | struct list_head samples; |
21 | struct list_head sample_cache; | ||
21 | struct sample_queue *last_sample; | 22 | struct sample_queue *last_sample; |
22 | }; | 23 | }; |
23 | 24 | ||