13#ifndef FASTLED_DEFAULT_SLAB_SIZE
14#define FASTLED_DEFAULT_SLAB_SIZE 8
20#if defined(FASTLED_TESTING)
24 virtual ~MallocFreeHook() =
default;
25 virtual void onMalloc(
void* ptr, fl::size size) = 0;
26 virtual void onFree(
void* ptr) = 0;
30void SetMallocFreeHook(MallocFreeHook* hook);
33void ClearMallocFreeHook();
39void*
Malloc(fl::size size);
92 fl::size size =
sizeof(T) * n;
98 return static_cast<T*
>(ptr);
110 template <
typename U,
typename... Args>
112 if (p ==
nullptr)
return;
117 template <
typename U>
119 if (p ==
nullptr)
return;
136 template <
typename U>
145 template <
typename U>
163 template <
typename U,
typename... Args>
165 if (p ==
nullptr)
return;
170 template <
typename U>
172 if (p ==
nullptr)
return;
182template <
typename T, fl::size SLAB_SIZE = FASTLED_DEFAULT_SLAB_SIZE>
187 static constexpr fl::size
BLOCK_SIZE =
sizeof(T) >
sizeof(
void*) ?
sizeof(T) : sizeof(void*);
238 for (
Slab* slab =
slabs_; slab; slab = slab->next) {
268 fl::i32 start = slab->
allocated_blocks.find_run(
false,
static_cast<fl::u32
>(n));
271 for (fl::size i = 0; i < n; ++i) {
290 for (
Slab* slab =
slabs_; slab; slab = slab->next) {
291 u8* slab_start = slab->memory;
295 if (block_ptr >= slab_start && block_ptr < slab_end) {
296 fl::size block_index = (block_ptr - slab_start) /
BLOCK_SIZE;
299 for (fl::size i = 0; i < n; ++i) {
301 slab->allocated_blocks.set(block_index + i,
false);
305 slab->allocated_count -= n;
328 other.slabs_ =
nullptr;
329 other.total_allocated_ = 0;
330 other.total_deallocated_ = 0;
334 if (
this != &other) {
339 other.slabs_ =
nullptr;
340 other.total_allocated_ = 0;
341 other.total_deallocated_ = 0;
355 return static_cast<T*
>(ptr);
359 ptr = malloc(
sizeof(T) * n);
363 return static_cast<T*
>(ptr);
372 bool found_in_slab =
false;
373 for (
Slab* slab =
slabs_; slab; slab = slab->next) {
374 u8* slab_start = slab->memory;
378 if (block_ptr >= slab_start && block_ptr < slab_end) {
380 found_in_slab =
true;
385 if (!found_in_slab) {
399 for (
Slab* slab =
slabs_; slab; slab = slab->next) {
419template <
typename T, fl::size SLAB_SIZE = FASTLED_DEFAULT_SLAB_SIZE>
432 template <
typename U>
456 template <
typename U>
487 template <
typename U,
typename... Args>
489 if (p ==
nullptr)
return;
494 template <
typename U>
496 if (p ==
nullptr)
return;
514 return !(*
this == other);
520template <
typename T, fl::size N,
typename BaseAllocator = fl::allocator<T>>
550 template <
typename U>
577 if (
this != &other) {
598 template <
typename U>
626 if (free_slot >= 0 &&
static_cast<fl::size
>(free_slot) < N) {
628 m_free_bits.set(
static_cast<fl::u32
>(free_slot),
true);
654 T* inlined_end = inlined_start + N;
656 if (p >= inlined_start && p < inlined_end) {
658 fl::size slot_index = (p - inlined_start);
659 for (fl::size i = 0; i < n; ++i) {
660 if (slot_index + i < N) {
676 template <
typename U,
typename... Args>
678 if (p ==
nullptr)
return;
683 template <
typename U>
685 if (p ==
nullptr)
return;
758 return !(*
this == other);
763template <
typename T, fl::size N>
767template <
typename T, fl::size N, fl::size SLAB_SIZE = 8>
771template <
typename T, fl::size N>
static T * Alloc(fl::size n)
static constexpr fl::size BLOCK_SIZE
fl::size getTotalDeallocated() const
static constexpr fl::size BLOCKS_PER_SLAB
SlabAllocator & operator=(const SlabAllocator &)=delete
void deallocate(T *ptr, fl::size n=1)
fl::size total_allocated_
SlabAllocator(const SlabAllocator &)=delete
void * allocateFromSlab(fl::size n=1)
fl::size getTotalAllocated() const
static constexpr fl::size SLAB_MEMORY_SIZE
T * allocate(fl::size n=1)
SlabAllocator(SlabAllocator &&other) noexcept
fl::size getSlabCount() const
void * findContiguousBlocks(Slab *slab, fl::size n)
fl::size total_deallocated_
SlabAllocator & operator=(SlabAllocator &&other) noexcept
void deallocateToSlab(void *ptr, fl::size n=1)
fl::size getActiveAllocations() const
allocator_inlined() noexcept=default
bool is_using_inlined() const
allocator_inlined & operator=(const allocator_inlined &other) noexcept
void cleanup_base_allocator_impl(fl::true_type)
void cleanup_base_allocator()
InlinedStorage m_inlined_storage
void deallocate(T *p, fl::size n)
BaseAllocator m_base_allocator
fl::size total_size() const
static auto has_cleanup_impl(int) -> decltype(fl::declval< U >().cleanup(), fl::true_type{})
~allocator_inlined() noexcept
fl::bitset_fixed< N > m_free_bits
fl::size m_active_allocations
allocator_inlined(const allocator_inlined< U, N, typename BaseAllocator::template rebind< U >::other > &other) noexcept
bool operator!=(const allocator_inlined &other) const noexcept
void construct(U *p, Args &&... args)
decltype(has_cleanup_impl< BaseAllocator >(0)) has_cleanup
const T & const_reference
ptrdiff_t difference_type
static fl::false_type has_cleanup_impl(...)
void cleanup_base_allocator_impl(fl::false_type)
bool operator==(const allocator_inlined &other) const noexcept
fl::size inlined_capacity() const
const T * get_inlined_ptr() const
allocator_inlined< U, N, typename BaseAllocator::template rebind< U >::other > other
ptrdiff_t difference_type
void construct(U *p, Args &&... args)
allocator_psram(const allocator_psram< U > &) noexcept
const T & const_reference
allocator_psram() noexcept
void deallocate(T *p, fl::size n)
~allocator_psram() noexcept
allocator_psram< U > other
allocator_slab(const allocator_slab &other) noexcept
const T & const_reference
void deallocate(T *p, fl::size n)
allocator_slab(const allocator_slab< U, SLAB_SIZE > &other) noexcept
~allocator_slab() noexcept
allocator_slab() noexcept
static SlabAllocator< T, SLAB_SIZE > & get_allocator()
bool operator!=(const allocator_slab &other) const noexcept
void construct(U *p, Args &&... args)
ptrdiff_t difference_type
bool operator==(const allocator_slab &other) const noexcept
allocator_slab & operator=(const allocator_slab &other) noexcept
typename fl::conditional< fl::is_same< U, void >::value, allocator_slab< char, SLAB_SIZE >, allocator_slab< U, SLAB_SIZE > >::type other
ptrdiff_t difference_type
void construct(U *p, Args &&... args)
allocator(const allocator< U > &) noexcept
const T & const_reference
void deallocate(T *p, fl::size n)
To * bit_cast_ptr(void *storage) noexcept
__PTRDIFF_TYPE__ ptrdiff_t
integral_constant< bool, false > false_type
void * memfill(void *ptr, int value, fl::size num)
add_rvalue_reference< T >::type declval() noexcept
void SetPSRamAllocator(void *(*alloc)(fl::size), void(*free)(void *))
void PSRamDeallocate(void *ptr)
void * Malloc(fl::size size)
allocator_inlined< T, N, fl::allocator_slab< T > > allocator_inlined_slab
void * PSRamAllocate(fl::size size, bool zero)
integral_constant< bool, true > true_type
constexpr T && forward(typename remove_reference< T >::type &t) noexcept
allocator_inlined< T, N, fl::allocator_slab< T, SLAB_SIZE > > allocator_inlined_slab_psram
allocator_inlined< T, N, fl::allocator_psram< T > > allocator_inlined_psram
fl::bitset_fixed< BLOCKS_PER_SLAB > allocated_blocks
static constexpr bool value
#define FASTLED_UNUSED(x)