From 223b90d0d4e79f74ebafbd0db9aea70a3bf9b74b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Jan 2013 15:30:10 +0100 Subject: MusicBuffer: return memory to kernel when stopping playback Use the new HugeAllocator as backend for SliceBuffer and call HugeDiscard() when the last chunk was returned. --- src/util/SliceBuffer.hxx | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src/util') diff --git a/src/util/SliceBuffer.hxx b/src/util/SliceBuffer.hxx index 1f5ff873..c61f164f 100644 --- a/src/util/SliceBuffer.hxx +++ b/src/util/SliceBuffer.hxx @@ -20,10 +20,9 @@ #ifndef MPD_SLICE_BUFFER_HXX #define MPD_SLICE_BUFFER_HXX +#include "HugeAllocator.hxx" #include "gcc.h" -#include - #include #include @@ -66,10 +65,15 @@ class SliceBuffer { */ Slice *available; + size_t CalcAllocationSize() const { + return n_max * sizeof(Slice); + } + public: SliceBuffer(unsigned _count) :n_max(_count), n_initialized(0), n_allocated(0), - data(g_new(Slice, n_max)), available(nullptr) { + data((Slice *)HugeAllocate(CalcAllocationSize())), + available(nullptr) { assert(n_max > 0); } @@ -78,12 +82,19 @@ public: assertion checks for leaks */ assert(n_allocated == 0); - g_free(data); + HugeFree(data, CalcAllocationSize()); } SliceBuffer(const SliceBuffer &other) = delete; SliceBuffer &operator=(const SliceBuffer &other) = delete; + /** + * @return true if buffer allocation (by the constructor) has failed + */ + bool IsOOM() { + return data == nullptr; + } + unsigned GetCapacity() const { return n_max; } @@ -136,6 +147,14 @@ public: slice->next = available; available = slice; --n_allocated; + + /* give memory back to the kernel when the last slice + was freed */ + if (n_allocated == 0) { + HugeDiscard(data, CalcAllocationSize()); + n_initialized = 0; + available = nullptr; + } } }; -- cgit v1.2.3