diff --git a/src/mem/alloc.h b/src/mem/alloc.h index 38c89d1..096ad47 100644 --- a/src/mem/alloc.h +++ b/src/mem/alloc.h @@ -38,7 +38,10 @@ namespace snmalloc PMMediumslab = 2 }; - using SuperslabPagemap = Pagemap; + using SuperslabPagemap = std::conditional_t< + bits::is64(), + Pagemap, + FlatPagemap>; HEADER_GLOBAL SuperslabPagemap global_pagemap; /** @@ -131,7 +134,7 @@ namespace snmalloc }; static_assert( - SUPERSLAB_SIZE == Pagemap::GRANULARITY, + SUPERSLAB_SIZE == SuperslabPagemap::GRANULARITY, "The superslab size should be the same as the pagemap granularity"); #ifndef SNMALLOC_DEFAULT_PAGEMAP diff --git a/src/mem/pagemap.h b/src/mem/pagemap.h index 20b01e2..e0e73b1 100644 --- a/src/mem/pagemap.h +++ b/src/mem/pagemap.h @@ -21,6 +21,10 @@ namespace snmalloc static constexpr size_t CONTENT_BITS = bits::next_pow2_bits_const(sizeof(T)); + static_assert( + PAGEMAP_BITS - CONTENT_BITS < COVERED_BITS, + "Should use the FlatPageMap as it does not require a tree"); + static constexpr size_t BITS_FOR_LEAF = PAGEMAP_BITS - CONTENT_BITS; static constexpr size_t ENTRIES_PER_LEAF = 1 << BITS_FOR_LEAF; static constexpr size_t LEAF_MASK = ENTRIES_PER_LEAF - 1; @@ -224,4 +228,44 @@ namespace snmalloc } while (length > 0); } }; + + template + class FlatPagemap + { + private: + static constexpr size_t COVERED_BITS = + bits::ADDRESS_BITS - GRANULARITY_BITS; + static constexpr size_t CONTENT_BITS = + bits::next_pow2_bits_const(sizeof(T)); + static constexpr size_t ENTRIES = 1ULL << (COVERED_BITS + CONTENT_BITS); + static constexpr size_t SHIFT = GRANULARITY_BITS; + + public: + static constexpr size_t GRANULARITY = 1 << GRANULARITY_BITS; + + private: + std::atomic top[ENTRIES]; + + public: + T get(void* p) + { + return top[(size_t)p >> SHIFT].load(std::memory_order_relaxed); + } + + void set(void* p, T x) + { + top[(size_t)p >> SHIFT].store(x, std::memory_order_relaxed); + } + + void set_range(void* p, T x, size_t length) + { + size_t index = (size_t)p >> SHIFT; + do + { + top[index].store(x, std::memory_order_relaxed); + index++; + length--; + } while (length > 0); + } + }; }