From 333e57a99a9863c373eacf6ddffe9c37b81aa2c0 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 17 May 2022 11:42:09 +0100 Subject: [PATCH 1/4] Add a pipe operation to ranges The ranges are naturally put together with pipes. This commit does some template magic to make the code more readable. There should be now functional changes with this change. --- src/snmalloc/backend/backend.h | 69 ++++++++++--------- src/snmalloc/backend_helpers/commitrange.h | 7 +- src/snmalloc/backend_helpers/globalrange.h | 6 +- .../backend_helpers/largebuddyrange.h | 16 ++++- src/snmalloc/backend_helpers/logrange.h | 10 ++- .../backend_helpers/pagemapregisterrange.h | 8 ++- src/snmalloc/backend_helpers/range_helpers.h | 20 ++++++ .../backend_helpers/smallbuddyrange.h | 9 ++- src/snmalloc/backend_helpers/statsrange.h | 7 +- src/snmalloc/backend_helpers/subrange.h | 9 ++- 10 files changed, 119 insertions(+), 42 deletions(-) diff --git a/src/snmalloc/backend/backend.h b/src/snmalloc/backend/backend.h index dda05abd8..5486e42aa 100644 --- a/src/snmalloc/backend/backend.h +++ b/src/snmalloc/backend/backend.h @@ -98,11 +98,12 @@ namespace snmalloc #endif // Set up source of memory - using P = PalRange; using Base = std::conditional_t< fixed_range, EmptyRange, - PagemapRegisterRange>; + Pipe< + PalRange, + PagemapRegisterRange>>; static constexpr size_t MinBaseSizeBits() { @@ -117,50 +118,56 @@ namespace snmalloc } // Global range of memory - using GlobalR = GlobalRange>>; + using GlobalR = Pipe< + Base, + LargeBuddyRange<24, bits::BITS - 1, Pagemap, MinBaseSizeBits()>, + LogRange<2>, + GlobalRange<>>; #ifdef SNMALLOC_META_PROTECTED // Introduce two global ranges, so we don't mix Object and Meta - using CentralObjectRange = GlobalRange>>; - using CentralMetaRange = GlobalRange, // Use SubRange to introduce guard pages. - 24, - bits::BITS - 1, - Pagemap, - MinBaseSizeBits()>>>; + using CentralObjectRange = Pipe< + GlobalR, + LargeBuddyRange<24, bits::BITS - 1, Pagemap, MinBaseSizeBits()>, + LogRange<3>, + GlobalRange<>>; + + using CentralMetaRange = Pipe< + GlobalR, + SubRange, // Use SubRange to introduce guard pages. + LargeBuddyRange<24, bits::BITS - 1, Pagemap, MinBaseSizeBits()>, + LogRange<4>, + GlobalRange<>>; // Source for object allocations - using StatsObject = StatsRange>; + using StatsObject = + Pipe, StatsRange<>>; + using ObjectRange = - LogRange<5, LargeBuddyRange>; + Pipe, LogRange<5>>; + + using StatsMeta = Pipe, StatsRange<>>; - using StatsMeta = StatsRange>; + using MetaRange = Pipe< + StatsMeta, + LargeBuddyRange<21 - 6, bits::BITS - 1, Pagemap>, + SmallBuddyRange<>>; - using MetaRange = SmallBuddyRange< - LargeBuddyRange>; // Create global range that can service small meta-data requests. // Don't want to add this to the CentralMetaRange to move Commit outside the // lock on the common case. - using GlobalMetaRange = GlobalRange>; + using GlobalMetaRange = Pipe, GlobalRange<>>; using Stats = StatsCombiner; #else // Source for object allocations and metadata // No separation between the two - using Stats = StatsRange; - using ObjectRange = SmallBuddyRange< - LargeBuddyRange, 21, 21, Pagemap>>; - using GlobalMetaRange = GlobalRange; + using Stats = Pipe>; + using ObjectRange = Pipe< + Stats, + CommitRange, + LargeBuddyRange<21, 21, Pagemap>, + SmallBuddyRange<>>; + using GlobalMetaRange = Pipe>; #endif struct LocalState diff --git a/src/snmalloc/backend_helpers/commitrange.h b/src/snmalloc/backend_helpers/commitrange.h index d2e6d54ff..6dc623fda 100644 --- a/src/snmalloc/backend_helpers/commitrange.h +++ b/src/snmalloc/backend_helpers/commitrange.h @@ -1,15 +1,18 @@ #pragma once - #include "../pal/pal.h" +#include "empty_range.h" namespace snmalloc { - template + template class CommitRange { ParentRange parent{}; public: + template + using Apply = CommitRange; + static constexpr bool Aligned = ParentRange::Aligned; static constexpr bool ConcurrencySafe = ParentRange::ConcurrencySafe; diff --git a/src/snmalloc/backend_helpers/globalrange.h b/src/snmalloc/backend_helpers/globalrange.h index b21d4d08b..af9048db8 100644 --- a/src/snmalloc/backend_helpers/globalrange.h +++ b/src/snmalloc/backend_helpers/globalrange.h @@ -1,6 +1,7 @@ #pragma once #include "../ds/ds.h" +#include "empty_range.h" namespace snmalloc { @@ -8,7 +9,7 @@ namespace snmalloc * Makes the supplied ParentRange into a global variable, * and protects access with a lock. */ - template + template class GlobalRange { SNMALLOC_REQUIRE_CONSTINIT static inline ParentRange parent{}; @@ -20,6 +21,9 @@ namespace snmalloc SNMALLOC_REQUIRE_CONSTINIT static inline FlagWord spin_lock{}; public: + template + using Apply = GlobalRange; + static constexpr bool Aligned = ParentRange::Aligned; static constexpr bool ConcurrencySafe = true; diff --git a/src/snmalloc/backend_helpers/largebuddyrange.h b/src/snmalloc/backend_helpers/largebuddyrange.h index b81e392ef..f53fc0ba8 100644 --- a/src/snmalloc/backend_helpers/largebuddyrange.h +++ b/src/snmalloc/backend_helpers/largebuddyrange.h @@ -3,6 +3,7 @@ #include "../ds/ds.h" #include "../mem/mem.h" #include "buddy.h" +#include "empty_range.h" #include "range_helpers.h" #include @@ -183,11 +184,11 @@ namespace snmalloc * for */ template< - typename ParentRange, size_t REFILL_SIZE_BITS, size_t MAX_SIZE_BITS, SNMALLOC_CONCEPT(ConceptBuddyRangeMeta) Pagemap, - size_t MIN_REFILL_SIZE_BITS = 0> + size_t MIN_REFILL_SIZE_BITS = 0, + typename ParentRange = EmptyRange> class LargeBuddyRange { ParentRange parent{}; @@ -327,6 +328,17 @@ namespace snmalloc } public: + /** + * We use a nested Apply type to enable a Pipe operation. + */ + template + using Apply = LargeBuddyRange< + REFILL_SIZE_BITS, + MAX_SIZE_BITS, + Pagemap, + MIN_REFILL_SIZE_BITS, + ParentRange2>; + static constexpr bool Aligned = true; static constexpr bool ConcurrencySafe = false; diff --git a/src/snmalloc/backend_helpers/logrange.h b/src/snmalloc/backend_helpers/logrange.h index 432e8772c..8d5ef709a 100644 --- a/src/snmalloc/backend_helpers/logrange.h +++ b/src/snmalloc/backend_helpers/logrange.h @@ -1,5 +1,7 @@ #pragma once +#include "empty_range.h" + namespace snmalloc { /** @@ -8,12 +10,18 @@ namespace snmalloc * * ParentRange is what the range is logging calls to. */ - template + template class LogRange { ParentRange parent{}; public: + /** + * We use a nested Apply type to enable a Pipe operation. + */ + template + using Apply = LogRange; + static constexpr bool Aligned = ParentRange::Aligned; static constexpr bool ConcurrencySafe = ParentRange::ConcurrencySafe; diff --git a/src/snmalloc/backend_helpers/pagemapregisterrange.h b/src/snmalloc/backend_helpers/pagemapregisterrange.h index de60dd8da..207487f55 100644 --- a/src/snmalloc/backend_helpers/pagemapregisterrange.h +++ b/src/snmalloc/backend_helpers/pagemapregisterrange.h @@ -1,18 +1,22 @@ #pragma once #include "../pal/pal.h" +#include "empty_range.h" namespace snmalloc { template< SNMALLOC_CONCEPT(ConceptBackendMetaRange) Pagemap, - typename ParentRange, - bool CanConsolidate = true> + bool CanConsolidate = true, + typename ParentRange = EmptyRange> class PagemapRegisterRange { ParentRange state{}; public: + template + using Apply = PagemapRegisterRange; + constexpr PagemapRegisterRange() = default; static constexpr bool Aligned = ParentRange::Aligned; diff --git a/src/snmalloc/backend_helpers/range_helpers.h b/src/snmalloc/backend_helpers/range_helpers.h index a9dc43c86..a1065b12f 100644 --- a/src/snmalloc/backend_helpers/range_helpers.h +++ b/src/snmalloc/backend_helpers/range_helpers.h @@ -34,4 +34,24 @@ namespace snmalloc length -= align; } } + + template + struct PipeImpl; + + template + struct PipeImpl + { + using result = Only; + }; + + template + struct PipeImpl + { + public: + using result = + typename PipeImpl, Rest...>::result; + }; + + template + using Pipe = typename PipeImpl::result; } // namespace snmalloc diff --git a/src/snmalloc/backend_helpers/smallbuddyrange.h b/src/snmalloc/backend_helpers/smallbuddyrange.h index b212323b5..1033e91da 100644 --- a/src/snmalloc/backend_helpers/smallbuddyrange.h +++ b/src/snmalloc/backend_helpers/smallbuddyrange.h @@ -1,6 +1,7 @@ #pragma once #include "../pal/pal.h" +#include "empty_range.h" #include "range_helpers.h" namespace snmalloc @@ -142,7 +143,7 @@ namespace snmalloc } }; - template + template class SmallBuddyRange { ParentRange parent{}; @@ -179,6 +180,12 @@ namespace snmalloc } public: + /** + * We use a nested type Apply to enable a Pipe operation. + */ + template + using Apply = SmallBuddyRange; + static constexpr bool Aligned = true; static_assert(ParentRange::Aligned, "ParentRange must be aligned"); diff --git a/src/snmalloc/backend_helpers/statsrange.h b/src/snmalloc/backend_helpers/statsrange.h index 98a06aec3..f1c202a47 100644 --- a/src/snmalloc/backend_helpers/statsrange.h +++ b/src/snmalloc/backend_helpers/statsrange.h @@ -1,5 +1,7 @@ #pragma once +#include "empty_range.h" + #include namespace snmalloc @@ -7,7 +9,7 @@ namespace snmalloc /** * Used to measure memory usage. */ - template + template class StatsRange { ParentRange parent{}; @@ -16,6 +18,9 @@ namespace snmalloc static inline std::atomic peak_usage{}; public: + template + using Apply = StatsRange; + static constexpr bool Aligned = ParentRange::Aligned; static constexpr bool ConcurrencySafe = ParentRange::ConcurrencySafe; diff --git a/src/snmalloc/backend_helpers/subrange.h b/src/snmalloc/backend_helpers/subrange.h index 3c6617d7c..f345806c2 100644 --- a/src/snmalloc/backend_helpers/subrange.h +++ b/src/snmalloc/backend_helpers/subrange.h @@ -1,5 +1,6 @@ #pragma once #include "../mem/mem.h" +#include "empty_range.h" namespace snmalloc { @@ -8,12 +9,18 @@ namespace snmalloc * 2^RATIO_BITS. Will not return a the block at the start or * the end of the large allocation. */ - template + template class SubRange { ParentRange parent{}; public: + /** + * We use a nested Apply type to enable a Pipe operation. + */ + template + using Apply = SubRange; + constexpr SubRange() = default; static constexpr bool Aligned = ParentRange::Aligned; From 827ece06289fa6f3b1edc71802107f3764a34d43 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 17 May 2022 12:57:48 +0100 Subject: [PATCH 2/4] Add a comment --- src/snmalloc/backend_helpers/range_helpers.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/snmalloc/backend_helpers/range_helpers.h b/src/snmalloc/backend_helpers/range_helpers.h index a1065b12f..26b7398d9 100644 --- a/src/snmalloc/backend_helpers/range_helpers.h +++ b/src/snmalloc/backend_helpers/range_helpers.h @@ -35,15 +35,27 @@ namespace snmalloc } } + /** + * Forward definition to allow multiple template specialisations. + * + * This struct is used to recursively compose ranges. + */ template struct PipeImpl; + /** + * Base case of one range that needs nothing. + */ template struct PipeImpl { using result = Only; }; + /** + * Recursive case of applying a base range as an argument to the + * next, and then using that as the new base range. + */ template struct PipeImpl { @@ -52,6 +64,9 @@ namespace snmalloc typename PipeImpl, Rest...>::result; }; + /** + * Nice type so the caller doesn't need to call result explicitly. + */ template using Pipe = typename PipeImpl::result; } // namespace snmalloc From cf0e8b5defcfc7c6555f5cce0811bc700af009ed Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 17 May 2022 13:43:11 +0100 Subject: [PATCH 3/4] Update src/snmalloc/backend_helpers/range_helpers.h --- src/snmalloc/backend_helpers/range_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/snmalloc/backend_helpers/range_helpers.h b/src/snmalloc/backend_helpers/range_helpers.h index 26b7398d9..db1a12fb6 100644 --- a/src/snmalloc/backend_helpers/range_helpers.h +++ b/src/snmalloc/backend_helpers/range_helpers.h @@ -38,7 +38,7 @@ namespace snmalloc /** * Forward definition to allow multiple template specialisations. * - * This struct is used to recursively compose ranges. + * This struct is used to recursively compose ranges. */ template struct PipeImpl; From 967cf5dcccfcb2e808050b3f985cb0b589d6af20 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 17 May 2022 14:51:38 +0100 Subject: [PATCH 4/4] CR --- src/snmalloc/backend_helpers/commitrange.h | 3 +++ src/snmalloc/backend_helpers/globalrange.h | 3 +++ src/snmalloc/backend_helpers/pagemapregisterrange.h | 3 +++ src/snmalloc/backend_helpers/smallbuddyrange.h | 2 +- src/snmalloc/backend_helpers/statsrange.h | 3 +++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/snmalloc/backend_helpers/commitrange.h b/src/snmalloc/backend_helpers/commitrange.h index 6dc623fda..c8d7c616c 100644 --- a/src/snmalloc/backend_helpers/commitrange.h +++ b/src/snmalloc/backend_helpers/commitrange.h @@ -10,6 +10,9 @@ namespace snmalloc ParentRange parent{}; public: + /** + * We use a nested Apply type to enable a Pipe operation. + */ template using Apply = CommitRange; diff --git a/src/snmalloc/backend_helpers/globalrange.h b/src/snmalloc/backend_helpers/globalrange.h index af9048db8..565b4f311 100644 --- a/src/snmalloc/backend_helpers/globalrange.h +++ b/src/snmalloc/backend_helpers/globalrange.h @@ -21,6 +21,9 @@ namespace snmalloc SNMALLOC_REQUIRE_CONSTINIT static inline FlagWord spin_lock{}; public: + /** + * We use a nested Apply type to enable a Pipe operation. + */ template using Apply = GlobalRange; diff --git a/src/snmalloc/backend_helpers/pagemapregisterrange.h b/src/snmalloc/backend_helpers/pagemapregisterrange.h index 207487f55..e75b72fe3 100644 --- a/src/snmalloc/backend_helpers/pagemapregisterrange.h +++ b/src/snmalloc/backend_helpers/pagemapregisterrange.h @@ -14,6 +14,9 @@ namespace snmalloc ParentRange state{}; public: + /** + * We use a nested Apply type to enable a Pipe operation. + */ template using Apply = PagemapRegisterRange; diff --git a/src/snmalloc/backend_helpers/smallbuddyrange.h b/src/snmalloc/backend_helpers/smallbuddyrange.h index 1033e91da..b19919050 100644 --- a/src/snmalloc/backend_helpers/smallbuddyrange.h +++ b/src/snmalloc/backend_helpers/smallbuddyrange.h @@ -181,7 +181,7 @@ namespace snmalloc public: /** - * We use a nested type Apply to enable a Pipe operation. + * We use a nested Apply type to enable a Pipe operation. */ template using Apply = SmallBuddyRange; diff --git a/src/snmalloc/backend_helpers/statsrange.h b/src/snmalloc/backend_helpers/statsrange.h index f1c202a47..49b18f729 100644 --- a/src/snmalloc/backend_helpers/statsrange.h +++ b/src/snmalloc/backend_helpers/statsrange.h @@ -18,6 +18,9 @@ namespace snmalloc static inline std::atomic peak_usage{}; public: + /** + * We use a nested Apply type to enable a Pipe operation. + */ template using Apply = StatsRange;