4#ifndef WPI_MEMORY_MEMORY_POOL_COLLECTION_HPP_INCLUDED
5#define WPI_MEMORY_MEMORY_POOL_COLLECTION_HPP_INCLUDED
59 template <
class PoolType,
class BucketDistribution,
62 : WPI_EBO(detail::default_leak_checker<detail::memory_pool_collection_leak_handler>)
79 template <
typename... Args>
82 : arena_(block_size,
detail::forward<Args>(args)...),
83 stack_(allocate_block()),
100 arena_(
detail::move(other.arena_)),
101 stack_(
detail::move(other.stack_)),
102 pools_(
detail::move(other.pools_))
130 auto& pool = pools_.
get(node_size);
133 auto block = reserve_memory(pool, def_capacity());
134 pool.insert(block.memory, block.size);
137 auto mem = pool.allocate();
151 auto& pool = pools_.
get(node_size);
154 try_reserve_memory(pool, def_capacity());
155 return pool.empty() ? nullptr : pool.allocate();
158 return pool.allocate();
175 auto& pool = pools_.
get(node_size);
179 auto mem = pool.empty() ? nullptr : pool.allocate(count * node_size);
183 auto block = reserve_memory(pool, def_capacity());
184 pool.insert(block.memory, block.size);
186 mem = pool.allocate(count * node_size);
192 [&] {
return next_capacity() - pool.alignment() + 1; }, info());
194 block = reserve_memory(pool, count * node_size);
195 pool.insert(block.memory, block.size);
197 mem = pool.allocate(count * node_size);
214 auto& pool = pools_.
get(node_size);
217 try_reserve_memory(pool, def_capacity());
218 return pool.empty() ? nullptr : pool.allocate(count * node_size);
221 return pool.allocate(count * node_size);
229 pools_.
get(node_size).deallocate(
ptr);
240 pools_.
get(node_size).deallocate(
ptr);
249 pools_.
get(node_size).deallocate(
ptr, count * node_size);
260 pools_.
get(node_size).deallocate(
ptr, count * node_size);
271 void reserve(std::size_t node_size, std::size_t capacity)
274 auto& pool = pools_.
get(node_size);
275 reserve_memory(pool, capacity);
292 return pools_.
get(node_size).capacity();
301 return std::size_t(block_end() - stack_.
top());
325 std::size_t def_capacity() const noexcept
330 detail::fixed_memory_stack allocate_block()
335 const char* block_end() const noexcept
338 return static_cast<const char*
>(block.memory) + block.
size;
341 bool insert_rest(
typename pool_type::type& pool)
noexcept
343 if (
auto remaining = std::size_t(block_end() - stack_.
top()))
346 if (offset < remaining)
349 pool.insert(stack_.
top() + offset, remaining - offset);
357 void try_reserve_memory(
typename pool_type::type& pool, std::size_t capacity)
noexcept
363 pool.insert(mem, capacity);
366 memory_block reserve_memory(
typename pool_type::type& pool, std::size_t capacity)
373 stack_ = allocate_block();
379 return {mem, capacity};
382 memory_arena<allocator_type, false> arena_;
383 detail::fixed_memory_stack stack_;
384 free_list_array pools_;
386 friend allocator_traits<memory_pool_collection>;
389#if WPI_MEMORY_EXTERN_TEMPLATE
390 extern template class memory_pool_collection<node_pool, identity_buckets>;
391 extern template class memory_pool_collection<array_pool, identity_buckets>;
392 extern template class memory_pool_collection<small_node_pool, identity_buckets>;
394 extern template class memory_pool_collection<node_pool, log2_buckets>;
395 extern template class memory_pool_collection<array_pool, log2_buckets>;
396 extern template class memory_pool_collection<small_node_pool, log2_buckets>;
402 template <
class PoolType = node_pool,
class ImplAllocator = default_allocator>
406 template <
class Allocator>
413 template <
class Pool,
class BucketDist,
class RawAllocator>
425 std::size_t alignment)
430 auto mem = state.allocate_node(size);
431 state.on_allocate(size);
439 std::size_t alignment)
444 auto mem = state.allocate_array(count, size);
445 state.on_allocate(count * size);
451 std::size_t)
noexcept
453 state.deallocate_node(node, size);
454 state.on_deallocate(size);
460 std::size_t size, std::size_t)
noexcept
462 state.deallocate_array(
array, count, size);
463 state.on_deallocate(count * size);
469 return state.max_node_size();
475 return state.next_capacity();
488 template <
class Pool,
class BucketDist,
class RawAllocator>
499 std::size_t alignment)
noexcept
501 if (alignment > traits::max_alignment(state))
503 return state.try_allocate_node(size);
509 std::size_t size, std::size_t alignment)
noexcept
511 if (count * size > traits::max_array_size(state)
512 || alignment > traits::max_alignment(state))
514 return state.try_allocate_array(count, size);
520 std::size_t alignment)
noexcept
522 if (alignment > traits::max_alignment(state))
524 return state.try_deallocate_node(node, size);
530 std::size_t size, std::size_t alignment)
noexcept
532 if (count * size > traits::max_array_size(state)
533 || alignment > traits::max_alignment(state))
535 return state.try_deallocate_array(
array, count, size);
539#if WPI_MEMORY_EXTERN_TEMPLATE
540 extern template class allocator_traits<memory_pool_collection<node_pool, identity_buckets>>;
541 extern template class allocator_traits<
542 memory_pool_collection<array_pool, identity_buckets>>;
543 extern template class allocator_traits<
544 memory_pool_collection<small_node_pool, identity_buckets>>;
546 extern template class allocator_traits<memory_pool_collection<node_pool, log2_buckets>>;
547 extern template class allocator_traits<memory_pool_collection<array_pool, log2_buckets>>;
548 extern template class allocator_traits<
549 memory_pool_collection<small_node_pool, log2_buckets>>;
551 extern template class composable_allocator_traits<
552 memory_pool_collection<node_pool, identity_buckets>>;
553 extern template class composable_allocator_traits<
554 memory_pool_collection<array_pool, identity_buckets>>;
555 extern template class composable_allocator_traits<
556 memory_pool_collection<small_node_pool, identity_buckets>>;
558 extern template class composable_allocator_traits<
559 memory_pool_collection<node_pool, log2_buckets>>;
560 extern template class composable_allocator_traits<
561 memory_pool_collection<array_pool, log2_buckets>>;
562 extern template class composable_allocator_traits<
563 memory_pool_collection<small_node_pool, log2_buckets>>;
This class is a wrapper around std::array that does compile time size checking.
Definition array.h:26
Specialization of the allocator_traits for memory_pool_collection classes.
Definition memory_pool_collection.hpp:415
static std::size_t max_array_size(const allocator_type &state) noexcept
Definition memory_pool_collection.hpp:473
static void deallocate_node(allocator_type &state, void *node, std::size_t size, std::size_t) noexcept
Definition memory_pool_collection.hpp:450
static void * allocate_array(allocator_type &state, std::size_t count, std::size_t size, std::size_t alignment)
Definition memory_pool_collection.hpp:438
static void deallocate_array(allocator_type &state, void *array, std::size_t count, std::size_t size, std::size_t) noexcept
Definition memory_pool_collection.hpp:459
static std::size_t max_alignment(const allocator_type &) noexcept
Definition memory_pool_collection.hpp:480
static void * allocate_node(allocator_type &state, std::size_t size, std::size_t alignment)
Definition memory_pool_collection.hpp:424
std::true_type is_stateful
Definition memory_pool_collection.hpp:418
static std::size_t max_node_size(const allocator_type &state) noexcept
Definition memory_pool_collection.hpp:467
The default specialization of the allocator_traits for a RawAllocator.
Definition allocator_traits.hpp:292
static void * try_allocate_array(allocator_type &state, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition memory_pool_collection.hpp:508
static bool try_deallocate_node(allocator_type &state, void *node, std::size_t size, std::size_t alignment) noexcept
Definition memory_pool_collection.hpp:519
static void * try_allocate_node(allocator_type &state, std::size_t size, std::size_t alignment) noexcept
Definition memory_pool_collection.hpp:498
static bool try_deallocate_array(allocator_type &state, void *array, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition memory_pool_collection.hpp:529
The default specialization of the composable_allocator_traits for a ComposableAllocator.
Definition allocator_traits.hpp:500
void * allocate(const char *end, std::size_t size, std::size_t alignment, std::size_t fence_size=debug_fence_size) noexcept
Definition memory_stack.hpp:71
char * top() const noexcept
Definition memory_stack.hpp:107
std::size_t size() const noexcept
Definition free_list_array.hpp:77
std::size_t max_node_size() const noexcept
Definition free_list_array.hpp:83
FreeList & get(std::size_t node_size) const noexcept
Definition free_list_array.hpp:68
Definition debug_helpers.hpp:102
no_leak_checker & operator=(no_leak_checker &&) noexcept
Definition debug_helpers.hpp:108
memory_block allocate_block()
Definition memory_arena.hpp:350
memory_block current_block() const noexcept
Definition memory_arena.hpp:362
std::size_t next_block_size() const noexcept
Definition memory_arena.hpp:415
allocator_type & get_allocator() noexcept
Definition memory_arena.hpp:425
bool owns(const void *ptr) const noexcept
Definition memory_arena.hpp:379
A stateful RawAllocator that behaves as a collection of multiple memory_pool objects.
Definition memory_pool_collection.hpp:63
memory_pool_collection(std::size_t max_node_size, std::size_t block_size, Args &&... args)
Definition memory_pool_collection.hpp:80
std::size_t next_capacity() const noexcept
Definition memory_pool_collection.hpp:307
void deallocate_node(void *ptr, std::size_t node_size) noexcept
Definition memory_pool_collection.hpp:227
BucketDistribution bucket_distribution
Definition memory_pool_collection.hpp:72
std::size_t capacity_left() const noexcept
Definition memory_pool_collection.hpp:299
make_block_allocator_t< BlockOrRawAllocator > allocator_type
Definition memory_pool_collection.hpp:70
allocator_type & get_allocator() noexcept
Definition memory_pool_collection.hpp:314
memory_pool_collection & operator=(memory_pool_collection &&other) noexcept
Definition memory_pool_collection.hpp:106
void reserve(std::size_t node_size, std::size_t capacity)
Definition memory_pool_collection.hpp:271
PoolType pool_type
Definition memory_pool_collection.hpp:71
void * allocate_node(std::size_t node_size)
Definition memory_pool_collection.hpp:126
void * allocate_array(std::size_t count, std::size_t node_size)
Definition memory_pool_collection.hpp:170
bool try_deallocate_array(void *ptr, std::size_t count, std::size_t node_size) noexcept
Definition memory_pool_collection.hpp:256
void * try_allocate_array(std::size_t count, std::size_t node_size) noexcept
Definition memory_pool_collection.hpp:210
void deallocate_array(void *ptr, std::size_t count, std::size_t node_size) noexcept
Definition memory_pool_collection.hpp:247
~memory_pool_collection() noexcept=default
std::size_t pool_capacity_left(std::size_t node_size) const noexcept
Definition memory_pool_collection.hpp:289
bool try_deallocate_node(void *ptr, std::size_t node_size) noexcept
Definition memory_pool_collection.hpp:236
void * try_allocate_node(std::size_t node_size) noexcept
Definition memory_pool_collection.hpp:147
std::size_t max_node_size() const noexcept
Definition memory_pool_collection.hpp:280
#define WPI_MEMORY_LOG_PREFIX
Definition config.hpp:46
#define WPI_ALIAS_TEMPLATE(Name,...)
Definition config.hpp:73
implementation_defined default_allocator
The default RawAllocator that will be used as BlockAllocator in memory arenas.
Definition default_allocator.hpp:32
implementation_defined make_block_allocator_t
Takes either a BlockAllocator or a RawAllocator.
Definition memory_arena.hpp:622
@ alignment_memory
Marks buffer memory used to ensure proper alignment.
Class wpi::memory::memory_arena and related functionality regarding BlockAllocators.
detail namespace with internal helper functions
Definition input_adapters.h:32
std::size_t align_offset(std::uintptr_t address, std::size_t alignment) noexcept
Definition align.hpp:26
void debug_fill(void *, std::size_t, debug_magic) noexcept
Definition debug_helpers.hpp:45
constexpr std::size_t max_alignment
Definition align.hpp:42
void check_allocation_size(std::size_t passed, Func f, const allocator_info &info)
Definition error.hpp:264
std::remove_reference< T >::type && move(T &&arg) noexcept
Definition utility.hpp:25
std::size_t alignment_for(std::size_t size) noexcept
Memory namespace.
Definition heap_allocator.hpp:20
Foonathan namespace.
Definition ntcore_cpp.h:26
Contains information about an allocator.
Definition error.hpp:23
Definition free_list_array.hpp:102
Definition free_list_array.hpp:117
Definition memory_pool_collection.hpp:29
void operator()(std::ptrdiff_t amount)
A BucketDistribution for memory_pool_collection defining that there is a bucket, i....
Definition memory_pool_collection.hpp:39
A BucketDistribution for memory_pool_collection defining that there is a bucket, i....
Definition memory_pool_collection.hpp:48
std::size_t size
The size of the memory block (might be 0).
Definition memory_arena.hpp:30
void * memory
The address of the memory block (might be nullptr).
Definition memory_arena.hpp:29
#define WPI_MEMORY_ASSERT(Expr)
Definition assert.hpp:46
#define WPI_MEMORY_ASSERT_MSG(Expr, Msg)
Definition assert.hpp:47