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.
This commit is contained in:
Max Kellermann 2013-01-04 15:30:10 +01:00
parent 692b2cfb79
commit 223b90d0d4
2 changed files with 28 additions and 5 deletions

View File

@ -21,6 +21,7 @@
#include "MusicBuffer.hxx"
#include "MusicChunk.hxx"
#include "util/SliceBuffer.hxx"
#include "mpd_error.h"
#include <glib.h>
@ -32,7 +33,10 @@ struct music_buffer : public SliceBuffer<music_chunk> {
music_buffer(unsigned num_chunks)
:SliceBuffer(num_chunks),
mutex(g_mutex_new()) {}
mutex(g_mutex_new()) {
if (IsOOM())
MPD_ERROR("Failed to allocate buffer");
}
~music_buffer() {
g_mutex_free(mutex);

View File

@ -20,10 +20,9 @@
#ifndef MPD_SLICE_BUFFER_HXX
#define MPD_SLICE_BUFFER_HXX
#include "HugeAllocator.hxx"
#include "gcc.h"
#include <glib.h>
#include <utility>
#include <new>
@ -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;
}
}
};