19#include "pw_allocator/block/poisonable.h"
20#include "pw_allocator/config.h"
21#include "pw_allocator/hardening.h"
22#include "pw_allocator/layout.h"
23#include "pw_assert/assert.h"
24#include "pw_bytes/alignment.h"
26namespace pw::allocator::internal {
56template <
typename Derived,
typename BlockType_,
typename ItemType_>
59 using BlockType = BlockType_;
60 using ItemType = ItemType_;
65 [[nodiscard]]
constexpr bool empty()
const {
66 return derived()->items_.empty();
71 return max_inner_size_;
83 [[nodiscard]]
bool Add(BlockType& block);
88 return empty() ? nullptr : derived()->DoFindLargest();
95 return empty() ? nullptr : derived()->DoRemoveAny();
102 [[nodiscard]]
bool Remove(BlockType& block) {
103 return block.InnerSize() >=
sizeof(ItemType) && derived()->DoRemove(block);
114 return derived()->DoRemoveCompatible(layout);
118 void Clear() { derived()->items_.clear(); }
133 template <
typename Iterator,
typename Predicate>
136 Predicate predicate);
150 template <
typename Iterator>
153 return iter != last ? BlockType::FromUsableSpace(&(*iter)) :
nullptr;
158 template <
typename Iterator>
170 return *(std::launder(
reinterpret_cast<ItemType*
>(block.UsableSpace())));
174 constexpr Derived* derived() {
return static_cast<Derived*
>(
this); }
175 constexpr const Derived* derived()
const {
176 return static_cast<const Derived*
>(
this);
180 size_t max_inner_size_ = std::numeric_limits<size_t>::max();
187template <
typename T,
typename U =
size_t>
189 return static_cast<U
>(cpp20::countr_zero(t));
196template <
typename T,
typename U =
size_t>
198 return static_cast<U
>(cpp20::countl_zero(t));
205template <
typename Derived,
typename BlockType,
typename ItemType>
206constexpr BucketBase<Derived, BlockType, ItemType>::BucketBase() {
207 if constexpr (is_poisonable_v<BlockType>) {
208 static_assert(BlockType::kPoisonOffset >=
sizeof(ItemType),
209 "Block type does not reserve sufficient space for an item");
213template <
typename Derived,
typename BlockType,
typename ItemType>
215 size_t max_inner_size) {
216 if constexpr (Hardening::kIncludesDebugChecks) {
219 max_inner_size_ = max_inner_size;
222template <
typename Derived,
typename BlockType,
typename ItemType>
224 if (block.InnerSize() <
sizeof(ItemType)) {
227 if constexpr (Hardening::kIncludesDebugChecks) {
228 PW_ASSERT(block.InnerSize() <= max_inner_size_);
229 PW_ASSERT(IsAlignedAs<ItemType>(block.UsableSpace()));
231 derived()->DoAdd(block);
235template <
typename Derived,
typename BlockType,
typename ItemType>
236template <
typename Iterator,
typename Predicate>
238 Iterator before_first, Iterator last, Predicate predicate) {
239 Iterator prev = before_first;
240 Iterator iter = prev;
242 for (; iter != last; ++iter) {
243 if (predicate(*iter)) {
251template <
typename Derived,
typename BlockType,
typename ItemType>
254 return [layout](ItemType& item) {
255 auto* block = BlockType::FromUsableSpace(&item);
256 return block->CanAlloc(layout).ok();
260template <
typename Derived,
typename BlockType,
typename ItemType>
262 const ItemType& item2) {
263 const BlockType* block1 = BlockType::FromUsableSpace(&item1);
264 const BlockType* block2 = BlockType::FromUsableSpace(&item2);
265 return block1->InnerSize() < block2->InnerSize();
Definition: fast_sorted.h:35
static constexpr BlockType * GetBlockFromPrev(Iterator prev, Iterator last)
Definition: base.h:159
bool Add(BlockType &block)
Definition: base.h:223
static bool Compare(const ItemType &item1, const ItemType &item2)
Definition: base.h:261
bool Remove(BlockType &block)
Definition: base.h:102
static Iterator FindPrevIf(Iterator before_first, Iterator last, Predicate predicate)
Definition: base.h:237
constexpr size_t max_inner_size() const
Returns the configured maximum inner size for blocks in this bucket.
Definition: base.h:70
BlockType * RemoveAny()
Definition: base.h:94
constexpr void set_max_inner_size(size_t max_inner_size)
Definition: base.h:214
const BlockType * FindLargest() const
Definition: base.h:87
void Clear()
Removes all blocks from this bucket.
Definition: base.h:118
static ItemType & GetItemFrom(BlockType &block)
Definition: base.h:169
static constexpr BlockType * GetBlockFromIterator(Iterator iter, Iterator last)
Definition: base.h:151
static auto MakeCanAllocPredicate(Layout layout)
Definition: base.h:252
constexpr bool empty() const
Returns whether this buckets contains any free blocks.
Definition: base.h:65
BlockType * RemoveCompatible(Layout layout)
Definition: base.h:113
constexpr U CountRZero(T t)
Definition: base.h:188
constexpr U CountLZero(T t)
Definition: base.h:197