WPILibC++ 2025.1.1
Loading...
Searching...
No Matches
wpi::memory::memory_pool< PoolType, BlockOrRawAllocator > Class Template Reference

A stateful RawAllocator that manages nodes of fixed size. More...

#include <wpi/memory/memory_pool.hpp>

Public Types

using allocator_type = make_block_allocator_t<BlockOrRawAllocator>
 
using pool_type = PoolType
 

Public Member Functions

template<typename... Args>
 memory_pool (std::size_t node_size, std::size_t block_size, Args &&... args)
 
 ~memory_pool () noexcept
 
void * allocate_node ()
 
void * try_allocate_node () noexcept
 
void * allocate_array (std::size_t n)
 
void * try_allocate_array (std::size_t n) noexcept
 
void deallocate_node (void *ptr) noexcept
 
bool try_deallocate_node (void *ptr) noexcept
 
void deallocate_array (void *ptr, std::size_t n) noexcept
 
bool try_deallocate_array (void *ptr, std::size_t n) noexcept
 
std::size_t node_size () const noexcept
 
std::size_t capacity_left () const noexcept
 
std::size_t next_capacity () const noexcept
 
allocator_typeget_allocator () noexcept
 
 memory_pool (memory_pool &&other) noexcept
 
memory_pooloperator= (memory_pool &&other) noexcept
 

Static Public Member Functions

static constexpr std::size_t min_block_size (std::size_t node_size, std::size_t number_of_nodes) noexcept
 

Static Public Attributes

static constexpr std::size_t min_node_size
 

Detailed Description

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
class wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >

A stateful RawAllocator that manages nodes of fixed size.

It uses a memory_arena with a given BlockOrRawAllocator defaulting to growing_block_allocator, subdivides them in small nodes of given size and puts them onto a free list. Allocation and deallocation simply remove or add nodes from this list and are thus fast. The way the list is maintained can be controlled via the PoolType which is either node_pool, array_pool or small_node_pool.
This kind of allocator is ideal for fixed size allocations and deallocations in any order, for example in a node based container like std::list. It is not so good for different allocation sizes and has some drawbacks for arrays as described in memory_pool_type.hpp.

Member Typedef Documentation

◆ allocator_type

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
using wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::allocator_type = make_block_allocator_t<BlockOrRawAllocator>

◆ pool_type

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
using wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::pool_type = PoolType

Constructor & Destructor Documentation

◆ memory_pool() [1/2]

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
template<typename... Args>
wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::memory_pool ( std::size_t node_size,
std::size_t block_size,
Args &&... args )
inline
Effects:
Creates it by specifying the size each node will have, the initial block size for the arena and other constructor arguments for the BlockAllocator. If the node_size is less than the min_node_size, the min_node_size will be the actual node size. It will allocate an initial memory block with given size from the BlockAllocator and puts it onto the free list.
Requires:
node_size must be a valid node size and block_size must be at least min_block_size(node_size, 1).

◆ ~memory_pool()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::~memory_pool ( )
inlinenoexcept
Effects:
Destroys the memory_pool by returning all memory blocks, regardless of properly deallocated back to the BlockAllocator.

◆ memory_pool() [2/2]

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::memory_pool ( memory_pool< PoolType, BlockOrRawAllocator > && other)
inlinenoexcept
Effects:
Moving a memory_pool object transfers ownership over the free list, i.e. the moved from pool is completely empty and the new one has all its memory. That means that it is not allowed to call deallocate_node() on a moved-from allocator even when passing it memory that was previously allocated by this object.

Member Function Documentation

◆ allocate_array()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
void * wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::allocate_array ( std::size_t n)
inline
Effects:
Allocates an array of nodes by searching for n continuous nodes on the list and removing them. Depending on the PoolType this can be a slow operation or not allowed at all. This can sometimes lead to a growth, even if technically there is enough continuous memory on the free list.
Returns:
An array of n nodes of size node_size() suitable aligned.
Throws:
Anything thrown by the used BlockAllocator's allocation function if a growth is needed, or bad_array_size if n * node_size() is too big.
Requires:
n must be valid array count.

◆ allocate_node()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
void * wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::allocate_node ( )
inline
Effects:
Allocates a single node by removing it from the free list. If the free list is empty, a new memory block will be allocated from the arena and put onto it. The new block size will be next_capacity() big.
Returns:
A node of size node_size() suitable aligned, i.e. suitable for any type where sizeof(T) < node_size().
Throws:
Anything thrown by the used BlockAllocator's allocation function if a growth is needed.

◆ capacity_left()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
std::size_t wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::capacity_left ( ) const
inlinenoexcept
Effects:
Returns the total amount of bytes remaining on the free list. Divide it by node_size() to get the number of nodes that can be allocated without growing the arena.
Note
Array allocations may lead to a growth even if the capacity_left left is big enough.

◆ deallocate_array()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
void wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::deallocate_array ( void * ptr,
std::size_t n )
inlinenoexcept
Effects:
Deallocates an array by putting it back onto the free list.
Requires:
ptr must be a result from a previous call to allocate_array() with the same n on the same free list, i.e. either this allocator object or a new object created by moving this to it.

◆ deallocate_node()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
void wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::deallocate_node ( void * ptr)
inlinenoexcept
Effects:
Deallocates a single node by putting it back onto the free list.
Requires:
ptr must be a result from a previous call to allocate_node() on the same free list, i.e. either this allocator object or a new object created by moving this to it.

◆ get_allocator()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
allocator_type & wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::get_allocator ( )
inlinenoexcept
Returns:
A reference to the BlockAllocator used for managing the arena.
Requires:
It is undefined behavior to move this allocator out into another object.

◆ min_block_size()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
static constexpr std::size_t wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::min_block_size ( std::size_t node_size,
std::size_t number_of_nodes )
inlinestaticconstexprnoexcept
Returns:
The minimum block size required for certain number of node.
Requires:
node_size must be a valid node size and number_of_nodes must be a non-zero value.
Note
MSVC's implementation of std::list for example is never empty and always allocates proxy nodes. To get enough memory for N elements of a list, number_of_nodes needs to include the proxy count in addition to N.

◆ next_capacity()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
std::size_t wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::next_capacity ( ) const
inlinenoexcept
Returns:
The size of the next memory block after the free list gets empty and the arena grows. capacity_left() will increase by this amount.
Note
Due to fence memory in debug mode this cannot be just divided by the node_size() to get the number of nodes.

◆ node_size()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
std::size_t wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::node_size ( ) const
inlinenoexcept
Returns:
The size of each node in the pool, this is either the same value as in the constructor or min_node_size if the value was too small.

◆ operator=()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
memory_pool & wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::operator= ( memory_pool< PoolType, BlockOrRawAllocator > && other)
inlinenoexcept

◆ try_allocate_array()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
void * wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::try_allocate_array ( std::size_t n)
inlinenoexcept
Effects:
Allocates an array of nodes similar to allocate_array(). But it will never allocate a new memory block.
Returns:
An array of n nodes of size node_size() suitable aligned or nullptr.

◆ try_allocate_node()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
void * wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::try_allocate_node ( )
inlinenoexcept
Effects:
Allocates a single node similar to allocate_node(). But if the free list is empty, a new block will not be allocated.
Returns:
A suitable aligned node of size node_size() or nullptr.

◆ try_deallocate_array()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
bool wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::try_deallocate_array ( void * ptr,
std::size_t n )
inlinenoexcept
Effects:
Deallocates an array but it does not be a result of a previous call to allocate_array().
Returns:
true if the node could be deallocated, false otherwise.
Note
Some free list implementations can deallocate any memory, doesn't matter where it is coming from.

◆ try_deallocate_node()

template<typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
bool wpi::memory::memory_pool< PoolType, BlockOrRawAllocator >::try_deallocate_node ( void * ptr)
inlinenoexcept
Effects:
Deallocates a single node but it does not be a result of a previous call to allocate_node().
Returns:
true if the node could be deallocated, false otherwise.
Note
Some free list implementations can deallocate any memory, doesn't matter where it is coming from.

Member Data Documentation

◆ min_node_size

template<class Type , class Alloc >
std::size_t wpi::memory::memory_pool< Type, Alloc >::min_node_size
staticconstexpr
Initial value:
=
implementation_defined

The documentation for this class was generated from the following file: