From fd88b8464bea9727b036e5194ccbf9d030d65d4f Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Thu, 1 Aug 2019 11:37:00 +0100 Subject: [PATCH] [NFC] Separate out support for aligned allocation from the FreeBSD PAL. NetBSD also supports `MAP_ALIGNED()` in `mmap` (according to the man page, at least). --- src/pal/pal_bsd_aligned.h | 55 +++++++++++++++++++++++++++++++++++++++ src/pal/pal_freebsd.h | 46 +++++--------------------------- 2 files changed, 62 insertions(+), 39 deletions(-) create mode 100644 src/pal/pal_bsd_aligned.h diff --git a/src/pal/pal_bsd_aligned.h b/src/pal/pal_bsd_aligned.h new file mode 100644 index 0000000..48b5989 --- /dev/null +++ b/src/pal/pal_bsd_aligned.h @@ -0,0 +1,55 @@ +#pragma once + +#if defined(__FreeBSD__) && !defined(_KERNEL) +# include "pal_bsd.h" + +namespace snmalloc +{ + /** + * FreeBSD-specific platform abstraction layer. + * + * This adds aligned allocation using `MAP_ALIGNED` to the generic BSD + * implementation. This flag is supported by NetBSD and FreeBSD. + */ + template + class PALBSD_Aligned : public PALBSD + { + public: + /** + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. + * + * This class adds support for aligned allocation. + */ + static constexpr uint64_t pal_features = + AlignedAllocation | PALBSD::pal_features; + + /** + * Reserve memory at a specific alignment. + */ + template + void* reserve(const size_t* size, size_t align) noexcept + { + // Alignment must be a power of 2. + assert(align == bits::next_pow2(align)); + + align = bits::max(4096, align); + + size_t log2align = bits::next_pow2_bits(align); + + void* p = mmap( + nullptr, + *size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED(log2align), + -1, + 0); + + if (p == MAP_FAILED) + error("Out of memory"); + + return p; + } + }; +} // namespace snmalloc +#endif diff --git a/src/pal/pal_freebsd.h b/src/pal/pal_freebsd.h index bb58966..10eec07 100644 --- a/src/pal/pal_freebsd.h +++ b/src/pal/pal_freebsd.h @@ -1,13 +1,7 @@ #pragma once #if defined(__FreeBSD__) && !defined(_KERNEL) -# include "../ds/bits.h" -# include "../mem/allocconfig.h" -# include "pal_bsd.h" - -# include -# include -# include +# include "pal_bsd_aligned.h" namespace snmalloc { @@ -17,45 +11,19 @@ namespace snmalloc * This adds FreeBSD-specific aligned allocation to the generic BSD * implementation. */ - class PALFBSD : public PALBSD + class PALFBSD : public PALBSD_Aligned { public: /** * Bitmap of PalFeatures flags indicating the optional features that this * PAL supports. - */ - static constexpr uint64_t pal_features = - AlignedAllocation | PALBSD::pal_features; - - /** - * Reserve memory. * - * FreeBSD supports requesting pages at an arbitrary alignment, which - * improves efficiency of snmalloc. + * The FreeBSD PAL does not currently add any features beyond those of a + * generic BSD with support for arbitrary alignment from `mmap`. This + * field is declared explicitly to remind anyone modifying this class to + * add new features that they should add any required feature flags. */ - template - void* reserve(const size_t* size, size_t align) noexcept - { - // Alignment must be a power of 2. - assert(align == bits::next_pow2(align)); - - align = bits::max(4096, align); - - size_t log2align = bits::next_pow2_bits(align); - - void* p = mmap( - nullptr, - *size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED(log2align), - -1, - 0); - - if (p == MAP_FAILED) - error("Out of memory"); - - return p; - } + static constexpr uint64_t pal_features = PALBSD_Aligned::pal_features; }; } // namespace snmalloc #endif