util/HugeAllocator: move MADV_DONTFORK setting to HugeForkCow()

Enforcing MADV_DONTFORK is a surprising limitation for this library
which aims to be generic.
This commit is contained in:
Max Kellermann
2017-09-19 19:52:02 +02:00
parent f6691579de
commit 8753e558f2
5 changed files with 38 additions and 7 deletions

View File

@@ -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;
}
@@ -88,6 +82,15 @@ HugeFree(void *p, size_t size) noexcept
munmap(p, AlignToPageSize(size));
}
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
{

View File

@@ -56,6 +56,13 @@ HugeAllocate(size_t size);
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
@@ -80,6 +87,11 @@ HugeFree(void *p, gcc_unused size_t size) noexcept
VirtualFree(p, 0, MEM_RELEASE);
}
static inline void
HugeForkCow(void *, size_t, bool) noexcept
{
}
static inline void
HugeDiscard(void *p, size_t size) noexcept
{
@@ -106,6 +118,11 @@ HugeFree(void *_p, size_t) noexcept
delete[] p;
}
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);
}

View File

@@ -74,6 +74,8 @@ public:
:n_max(_count),
data((Slice *)HugeAllocate(CalcAllocationSize())) {
assert(n_max > 0);
HugeForkCow(data, CalcAllocationSize(), false);
}
~SliceBuffer() {