Commit 223b90d0 authored by Max Kellermann's avatar Max Kellermann

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.
parent 692b2cfb
......@@ -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;
}
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment