summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2017-09-19 19:52:02 +0200
committerMax Kellermann <max@musicpd.org>2017-09-21 19:36:33 +0200
commit8753e558f24e177a355722f27463d9742b2bbd66 (patch)
tree3b1ff55900b49b8a87fac52915a759069243e5a4 /src/util
parentf6691579def38c60477d02cf57486364e4a0245c (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.cxx15
-rw-r--r--src/util/HugeAllocator.hxx21
-rw-r--r--src/util/SliceBuffer.hxx2
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() {