From 447a86c922801a9d268a121862c5ae5619bc7f91 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Jan 2013 20:27:29 +0100 Subject: SliceBuffer: lazy initialization Avoid page faults on MPD startup. This saves a lot of memory for an idle MPD. --- src/util/SliceBuffer.hxx | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'src/util') diff --git a/src/util/SliceBuffer.hxx b/src/util/SliceBuffer.hxx index 9ddad6b3..1f5ff873 100644 --- a/src/util/SliceBuffer.hxx +++ b/src/util/SliceBuffer.hxx @@ -47,6 +47,13 @@ class SliceBuffer { */ const unsigned n_max; + /** + * The number of slices that are initialized. This is used to + * avoid page faulting on the new allocation, so the kernel + * does not need to reserve physical memory pages. + */ + unsigned n_initialized; + /** * The number of slices currently allocated. */ @@ -61,15 +68,9 @@ class SliceBuffer { public: SliceBuffer(unsigned _count) - :n_max(_count), n_allocated(0), - data(g_new(Slice, n_max)), available(data) { + :n_max(_count), n_initialized(0), n_allocated(0), + data(g_new(Slice, n_max)), available(nullptr) { assert(n_max > 0); - - Slice *const last = data + n_max - 1; - for (Slice *slice = data; slice != last; ++slice) - slice->next = slice + 1; - - last->next = nullptr; } ~SliceBuffer() { @@ -97,12 +98,18 @@ public: template T *Allocate(Args&&... args) { - assert(n_allocated <= n_max); + assert(n_initialized <= n_max); + assert(n_allocated <= n_initialized); if (available == nullptr) { - /* out of (internal) memory, buffer is full */ - assert(n_allocated == n_max); - return nullptr; + if (n_initialized == n_max) { + /* out of (internal) memory, buffer is full */ + assert(n_allocated == n_max); + return nullptr; + } + + available = &data[n_initialized++]; + available->next = nullptr; } /* allocate a slice */ @@ -115,8 +122,9 @@ public: } void Free(T *value) { + assert(n_initialized <= n_max); assert(n_allocated > 0); - assert(n_allocated <= n_max); + assert(n_allocated <= n_initialized); Slice *slice = reinterpret_cast(value); assert(slice >= data && slice < data + n_max); -- cgit v1.2.3