Commit 8753e558 authored by Max Kellermann's avatar Max Kellermann

util/HugeAllocator: move MADV_DONTFORK setting to HugeForkCow()

Enforcing MADV_DONTFORK is a surprising limitation for this library which aims to be generic.
parent f6691579
...@@ -38,7 +38,10 @@ AsyncInputStream::AsyncInputStream(EventLoop &event_loop, const char *_url, ...@@ -38,7 +38,10 @@ AsyncInputStream::AsyncInputStream(EventLoop &event_loop, const char *_url,
deferred_seek(event_loop, BIND_THIS_METHOD(DeferredSeek)), deferred_seek(event_loop, BIND_THIS_METHOD(DeferredSeek)),
allocation(_buffer_size), allocation(_buffer_size),
buffer((uint8_t *)allocation.get(), _buffer_size), buffer((uint8_t *)allocation.get(), _buffer_size),
resume_at(_resume_at) {} resume_at(_resume_at)
{
allocation.ForkCow(false);
}
AsyncInputStream::~AsyncInputStream() AsyncInputStream::~AsyncInputStream()
{ {
......
...@@ -53,6 +53,8 @@ ThreadInputStream::Start() ...@@ -53,6 +53,8 @@ ThreadInputStream::Start()
void *p = HugeAllocate(buffer_size); void *p = HugeAllocate(buffer_size);
assert(p != nullptr); assert(p != nullptr);
HugeForkCow(p, buffer_size, false);
buffer = new CircularBuffer<uint8_t>((uint8_t *)p, buffer_size); buffer = new CircularBuffer<uint8_t>((uint8_t *)p, buffer_size);
thread.Start(); thread.Start();
} }
......
...@@ -73,12 +73,6 @@ HugeAllocate(size_t size) ...@@ -73,12 +73,6 @@ HugeAllocate(size_t size)
madvise(p, size, MADV_HUGEPAGE); madvise(p, size, MADV_HUGEPAGE);
#endif #endif
#ifdef MADV_DONTFORK
/* just in case MPD needs to fork, don't copy this allocation
to the child process, to reduce overhead */
madvise(p, size, MADV_DONTFORK);
#endif
return p; return p;
} }
...@@ -89,6 +83,15 @@ HugeFree(void *p, size_t size) noexcept ...@@ -89,6 +83,15 @@ HugeFree(void *p, size_t size) noexcept
} }
void void
HugeForkCow(void *p, size_t size, bool enable) noexcept
{
#ifdef MADV_DONTFORK
madvise(p, AlignToPageSize(size),
enable ? MADV_DOFORK : MADV_DONTFORK);
#endif
}
void
HugeDiscard(void *p, size_t size) noexcept HugeDiscard(void *p, size_t size) noexcept
{ {
#ifdef MADV_DONTNEED #ifdef MADV_DONTNEED
......
...@@ -57,6 +57,13 @@ void ...@@ -57,6 +57,13 @@ void
HugeFree(void *p, size_t size) noexcept; HugeFree(void *p, size_t size) noexcept;
/** /**
* Control whether this allocation is copied to newly forked child
* processes. Disabling that makes forking a little bit cheaper.
*/
void
HugeForkCow(void *p, size_t size, bool enable) noexcept;
/**
* Discard any data stored in the allocation and give the memory back * Discard any data stored in the allocation and give the memory back
* to the kernel. After returning, the allocation still exists and * to the kernel. After returning, the allocation still exists and
* can be reused at any time, but its contents are undefined. * can be reused at any time, but its contents are undefined.
...@@ -81,6 +88,11 @@ HugeFree(void *p, gcc_unused size_t size) noexcept ...@@ -81,6 +88,11 @@ HugeFree(void *p, gcc_unused size_t size) noexcept
} }
static inline void static inline void
HugeForkCow(void *, size_t, bool) noexcept
{
}
static inline void
HugeDiscard(void *p, size_t size) noexcept HugeDiscard(void *p, size_t size) noexcept
{ {
VirtualAlloc(p, size, MEM_RESET, PAGE_NOACCESS); VirtualAlloc(p, size, MEM_RESET, PAGE_NOACCESS);
...@@ -107,6 +119,11 @@ HugeFree(void *_p, size_t) noexcept ...@@ -107,6 +119,11 @@ HugeFree(void *_p, size_t) noexcept
} }
static inline void static inline void
HugeForkCow(void *, size_t, bool) noexcept
{
}
static inline void
HugeDiscard(void *, size_t) noexcept HugeDiscard(void *, size_t) noexcept
{ {
} }
...@@ -140,6 +157,10 @@ public: ...@@ -140,6 +157,10 @@ public:
return *this; return *this;
} }
void ForkCow(bool enable) noexcept {
HugeForkCow(data, size, enable);
}
void Discard() noexcept { void Discard() noexcept {
HugeDiscard(data, size); HugeDiscard(data, size);
} }
......
...@@ -74,6 +74,8 @@ public: ...@@ -74,6 +74,8 @@ public:
:n_max(_count), :n_max(_count),
data((Slice *)HugeAllocate(CalcAllocationSize())) { data((Slice *)HugeAllocate(CalcAllocationSize())) {
assert(n_max > 0); assert(n_max > 0);
HugeForkCow(data, CalcAllocationSize(), false);
} }
~SliceBuffer() { ~SliceBuffer() {
......
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