From 788e8c13d07e2a4ebb40d2f29c07716360bd5482 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 20 Sep 2022 10:50:09 +0100 Subject: [PATCH 1/5] Add a multiple region example. --- src/test/func/multi_region/multi_region.cc | 183 +++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/test/func/multi_region/multi_region.cc diff --git a/src/test/func/multi_region/multi_region.cc b/src/test/func/multi_region/multi_region.cc new file mode 100644 index 000000000..286fe5e30 --- /dev/null +++ b/src/test/func/multi_region/multi_region.cc @@ -0,0 +1,183 @@ +#include "test/setup.h" + +#include +#include +#include +#include +#include + +#ifdef assert +# undef assert +#endif +#define assert please_use_SNMALLOC_ASSERT + +using namespace snmalloc; + +/** + * A single fixed address range allocator configuration + */ +template +class MultiRegionConfig final : public CommonConfig +{ +public: + using PagemapEntry = DefaultPagemapEntry; + +private: + using ConcretePagemap = FlatPagemap; + + using Pagemap = BasicPagemap; + + static inline FlagWord pagemap_init_lock{}; + +public: + class LocalState + { + public: + using ObjectRange = Pipe< + EmptyRange<>, + LargeBuddyRange, + SmallBuddyRange>; + + // Dummy impl to keep concept happy. + using Stats = Pipe, StatsRange>; + + private: + ObjectRange object_range; + + void ensure_pagemap_init() + { + auto& pagemap = Pagemap::concretePagemap; + if (pagemap.is_initialised()) + return; + + FlagLock lock(pagemap_init_lock); + + if (pagemap.is_initialised()) + return; + + pagemap.init(); + } + + public: + // This should not be called. + using GlobalMetaRange = EmptyRange<>; + + // Where we get user allocations from. + ObjectRange* get_object_range() + { + return &object_range; + } + + // Where we get meta-data allocations from. + ObjectRange& get_meta_range() + { + // Use the object range to service meta-data requests. + return object_range; + } + + LocalState(void* base, size_t size) : object_range() + { + // Ensure the communal pagemap is initialised. + ensure_pagemap_init(); + + // Notify that pagemap requires committed memory for this range. + Pagemap::register_range(address_cast(base), size); + + // Fill the range owned by this region with memory. + object_range.dealloc_range(capptr::Arena::unsafe_from(base), size); + } + }; + + using Backend = BackendAllocator; + using Pal = PAL; + +private: +public: + static constexpr Flags Options{ + .CoreAllocOwnsLocalState = false, + .CoreAllocIsPoolAllocated = false, + .LocalAllocSupportsLazyInit = false}; + + static void register_clean_up() {} +}; + +using CustomConfig = MultiRegionConfig; +using FixedAlloc = LocalAllocator; +using CoreAlloc = CoreAllocator; + +class Region +{ +public: + FixedAlloc alloc; + +private: + CustomConfig::LocalState region_state; + + CoreAlloc core_alloc; + +public: + Region(void* base, size_t size) + : region_state(base, size), + core_alloc(&alloc.get_local_cache(), ®ion_state) + { + // Bind the core_alloc into the region local allocator + alloc.init(&core_alloc); + } +}; + +int main() +{ +#ifndef SNMALLOC_PASS_THROUGH // Depends on snmalloc specific features + setup(); + + // 28 is large enough to produce a nested allocator. + // It is also large enough for the example to run in. + // For 1MiB superslabs, SUPERSLAB_BITS + 4 is not big enough for the example. + auto size = bits::one_at_bit(28); + auto base = DefaultPal::reserve(size); + DefaultPal::notify_using(base, size); + auto end = pointer_offset(base, size); + std::cout << "Allocated region " << base << " - " + << pointer_offset(base, size) << std::endl; + + Region r(base, size); + auto& a = r.alloc; + + size_t object_size = 128; + size_t count = 0; + size_t i = 0; + while (true) + { + auto r1 = a.alloc(object_size); + count += object_size; + i++; + + if (i == 1024) + { + i = 0; + std::cout << "."; + } + // Run until we exhaust the fixed region. + // This should return null. + if (r1 == nullptr) + break; + + if (base > r1) + { + std::cout << "Allocated: " << r1 << std::endl; + abort(); + } + if (end < r1) + { + std::cout << "Allocated: " << r1 << std::endl; + abort(); + } + } + + std::cout << "Total allocated: " << count << " out of " << size << std::endl; + std::cout << "Overhead: 1/" << (double)size / (double)(size - count) + << std::endl; + + a.teardown(); +#endif +} From 1ba294dc985da1cbb174fe5744cc21b89f50e59f Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 20 Sep 2022 11:36:04 +0100 Subject: [PATCH 2/5] For GCC --- src/test/func/multi_region/multi_region.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/func/multi_region/multi_region.cc b/src/test/func/multi_region/multi_region.cc index 286fe5e30..ebd3e7e2c 100644 --- a/src/test/func/multi_region/multi_region.cc +++ b/src/test/func/multi_region/multi_region.cc @@ -93,10 +93,15 @@ class MultiRegionConfig final : public CommonConfig private: public: - static constexpr Flags Options{ - .CoreAllocOwnsLocalState = false, - .CoreAllocIsPoolAllocated = false, - .LocalAllocSupportsLazyInit = false}; + + constexpr static snmalloc::Flags Options{ + .IsQueueInline = true, + .CoreAllocOwnsLocalState = false, + .CoreAllocIsPoolAllocated = false, + .LocalAllocSupportsLazyInit = false, + .QueueHeadsAreTame = true, + .HasDomesticate = true, + }; static void register_clean_up() {} }; From 42b22a7651b474c96d62b2cf55bc67eac793c74d Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 20 Sep 2022 11:50:06 +0100 Subject: [PATCH 3/5] Fix fix --- src/test/func/multi_region/multi_region.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/func/multi_region/multi_region.cc b/src/test/func/multi_region/multi_region.cc index ebd3e7e2c..816af929c 100644 --- a/src/test/func/multi_region/multi_region.cc +++ b/src/test/func/multi_region/multi_region.cc @@ -100,7 +100,7 @@ class MultiRegionConfig final : public CommonConfig .CoreAllocIsPoolAllocated = false, .LocalAllocSupportsLazyInit = false, .QueueHeadsAreTame = true, - .HasDomesticate = true, + .HasDomesticate = false, }; static void register_clean_up() {} From ee1921773b933e98c86860f990f379880d2452b8 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 20 Sep 2022 13:59:28 +0100 Subject: [PATCH 4/5] Clangformat --- src/test/func/multi_region/multi_region.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/test/func/multi_region/multi_region.cc b/src/test/func/multi_region/multi_region.cc index 816af929c..ee7b41521 100644 --- a/src/test/func/multi_region/multi_region.cc +++ b/src/test/func/multi_region/multi_region.cc @@ -93,15 +93,14 @@ class MultiRegionConfig final : public CommonConfig private: public: - - constexpr static snmalloc::Flags Options{ - .IsQueueInline = true, - .CoreAllocOwnsLocalState = false, - .CoreAllocIsPoolAllocated = false, - .LocalAllocSupportsLazyInit = false, - .QueueHeadsAreTame = true, - .HasDomesticate = false, - }; + constexpr static snmalloc::Flags Options{ + .IsQueueInline = true, + .CoreAllocOwnsLocalState = false, + .CoreAllocIsPoolAllocated = false, + .LocalAllocSupportsLazyInit = false, + .QueueHeadsAreTame = true, + .HasDomesticate = false, + }; static void register_clean_up() {} }; From 926817445db0a3f88325b8c1b0ee726c8d580937 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 20 Sep 2022 16:18:48 +0100 Subject: [PATCH 5/5] Remove old comment. --- src/test/func/fixed_region/fixed_region.cc | 1 - src/test/func/multi_region/multi_region.cc | 1 - 2 files changed, 2 deletions(-) diff --git a/src/test/func/fixed_region/fixed_region.cc b/src/test/func/fixed_region/fixed_region.cc index 2c00c7b8c..7be2c9eb7 100644 --- a/src/test/func/fixed_region/fixed_region.cc +++ b/src/test/func/fixed_region/fixed_region.cc @@ -21,7 +21,6 @@ int main() // 28 is large enough to produce a nested allocator. // It is also large enough for the example to run in. - // For 1MiB superslabs, SUPERSLAB_BITS + 4 is not big enough for the example. auto size = bits::one_at_bit(28); auto oe_base = DefaultPal::reserve(size); DefaultPal::notify_using(oe_base, size); diff --git a/src/test/func/multi_region/multi_region.cc b/src/test/func/multi_region/multi_region.cc index ee7b41521..6648b1944 100644 --- a/src/test/func/multi_region/multi_region.cc +++ b/src/test/func/multi_region/multi_region.cc @@ -136,7 +136,6 @@ int main() // 28 is large enough to produce a nested allocator. // It is also large enough for the example to run in. - // For 1MiB superslabs, SUPERSLAB_BITS + 4 is not big enough for the example. auto size = bits::one_at_bit(28); auto base = DefaultPal::reserve(size); DefaultPal::notify_using(base, size);