Implement a FlatPagemap
The current pagemap assumes there is at least one level of indexing. This commit introduces a new pagemap that is completely flat. This is useful for 32bit, where there is no need to introduce the indexing structure. This pagemap is also considerably faster for 64bit platforms, but does require a global allocation of 16MiB of the flat page map.
This commit is contained in:
@@ -38,7 +38,10 @@ namespace snmalloc
|
||||
PMMediumslab = 2
|
||||
};
|
||||
|
||||
using SuperslabPagemap = Pagemap<SUPERSLAB_BITS, uint8_t, 0>;
|
||||
using SuperslabPagemap = std::conditional_t<
|
||||
bits::is64(),
|
||||
Pagemap<SUPERSLAB_BITS, uint8_t, 0>,
|
||||
FlatPagemap<SUPERSLAB_BITS, uint8_t>>;
|
||||
|
||||
HEADER_GLOBAL SuperslabPagemap global_pagemap;
|
||||
/**
|
||||
@@ -131,7 +134,7 @@ namespace snmalloc
|
||||
};
|
||||
|
||||
static_assert(
|
||||
SUPERSLAB_SIZE == Pagemap<SUPERSLAB_BITS, size_t, 0>::GRANULARITY,
|
||||
SUPERSLAB_SIZE == SuperslabPagemap::GRANULARITY,
|
||||
"The superslab size should be the same as the pagemap granularity");
|
||||
|
||||
#ifndef SNMALLOC_DEFAULT_PAGEMAP
|
||||
|
||||
@@ -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<size_t GRANULARITY_BITS, typename T>
|
||||
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<T> 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user