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:
parent
692b2cfb79
commit
223b90d0d4
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue