diff options
author | Max Kellermann <max@musicpd.org> | 2017-09-19 19:52:02 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2017-09-21 19:36:33 +0200 |
commit | 8753e558f24e177a355722f27463d9742b2bbd66 (patch) | |
tree | 3b1ff55900b49b8a87fac52915a759069243e5a4 /src/util | |
parent | f6691579def38c60477d02cf57486364e4a0245c (diff) |
util/HugeAllocator: move MADV_DONTFORK setting to HugeForkCow()
Enforcing MADV_DONTFORK is a surprising limitation for this library
which aims to be generic.
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/HugeAllocator.cxx | 15 | ||||
-rw-r--r-- | src/util/HugeAllocator.hxx | 21 | ||||
-rw-r--r-- | src/util/SliceBuffer.hxx | 2 |
3 files changed, 32 insertions, 6 deletions
diff --git a/src/util/HugeAllocator.cxx b/src/util/HugeAllocator.cxx index 5116a5923..6fcdad953 100644 --- a/src/util/HugeAllocator.cxx +++ b/src/util/HugeAllocator.cxx @@ -73,12 +73,6 @@ HugeAllocate(size_t size) madvise(p, size, MADV_HUGEPAGE); #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; } @@ -89,6 +83,15 @@ HugeFree(void *p, size_t size) noexcept } 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 { #ifdef MADV_DONTNEED diff --git a/src/util/HugeAllocator.hxx b/src/util/HugeAllocator.hxx index 46b65e29a..421cf7da4 100644 --- a/src/util/HugeAllocator.hxx +++ b/src/util/HugeAllocator.hxx @@ -57,6 +57,13 @@ void 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 * to the kernel. After returning, the allocation still exists and * can be reused at any time, but its contents are undefined. @@ -81,6 +88,11 @@ HugeFree(void *p, gcc_unused size_t size) noexcept } static inline void +HugeForkCow(void *, size_t, bool) noexcept +{ +} + +static inline void HugeDiscard(void *p, size_t size) noexcept { VirtualAlloc(p, size, MEM_RESET, PAGE_NOACCESS); @@ -107,6 +119,11 @@ HugeFree(void *_p, size_t) noexcept } static inline void +HugeForkCow(void *, size_t, bool) noexcept +{ +} + +static inline void HugeDiscard(void *, size_t) noexcept { } @@ -140,6 +157,10 @@ public: return *this; } + void ForkCow(bool enable) noexcept { + HugeForkCow(data, size, enable); + } + void Discard() noexcept { HugeDiscard(data, size); } diff --git a/src/util/SliceBuffer.hxx b/src/util/SliceBuffer.hxx index a623ab7a6..de553fcb4 100644 --- a/src/util/SliceBuffer.hxx +++ b/src/util/SliceBuffer.hxx @@ -74,6 +74,8 @@ public: :n_max(_count), data((Slice *)HugeAllocate(CalcAllocationSize())) { assert(n_max > 0); + + HugeForkCow(data, CalcAllocationSize(), false); } ~SliceBuffer() { |