29 assert(
freeList_[level].next !=
nullptr &&
"pop front from an empty list");
36 assert(level <
kMaxLevel &&
"level is larger than the maximum possible level");
41 bool isEmpty(std::size_t level)
const noexcept {
46 std::size_t index =
reinterpret_cast<std::byte*
>(block) -
beginBuffer_;
47 std::size_t buddyIndex = index ^ blockSize;
76 explicit BuddyMemoryResource(
void* buffer, std::size_t capacity, std::size_t alignment =
alignof(std::max_align_t))
80 if (!std::align(alignment, alignment, buffer, capacity)) {
81 throw std::bad_alloc();
86 assert(
capacity_ > 0 &&
"buffer capacity must be non-zero after alignment");
87 std::size_t level = std::countr_zero(
capacity_);
91 virtual void*
allocateImp(std::size_t bytes, std::size_t alignment)
override {
92 std::size_t requiredLevel = std::countr_zero(std::bit_ceil(std::max(bytes, alignment)));
95 std::size_t level = requiredLevel;
102 throw std::bad_alloc();
106 while (level > requiredLevel) {
110 BuddyBlock* secondHalf =
reinterpret_cast<BuddyBlock*
>(
reinterpret_cast<std::byte*
>(block) + levelSize);
117 virtual void deallocateImp(
void* address, std::size_t bytes, std::size_t alignment)
override {
122 std::size_t level = std::countr_zero(std::bit_ceil(std::max(bytes, alignment)));
127 address = std::min(address,
static_cast<void*
>(buddy));
virtual void * allocateImp(std::size_t bytes, std::size_t alignment) override
bool eraseBlock(BuddyBlock *block, std::size_t level) noexcept
bool isEmpty(std::size_t level) const noexcept
BuddyBlock * popFront(std::size_t level) noexcept
BuddyBlock * getBuddy(BuddyBlock *block, std::size_t blockSize) const noexcept
static constexpr std::size_t kMaxLevel
virtual void deallocateImp(void *address, std::size_t bytes, std::size_t alignment) override
void pushFront(BuddyBlock *block, std::size_t level) noexcept
BuddyMemoryResource(void *buffer, std::size_t capacity, std::size_t alignment=alignof(std::max_align_t))
Constructs a buddy allocator over a user-provided buffer.
BuddyBlock freeList_[kMaxLevel]
std::size_t getLevelSize(std::size_t level) const noexcept
A memory resource holder interface for the PolymorphicAllocator. Responsible for allocate and dealloc...