Bitcoin Core  27.99.0
P2P Digital Currency
Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES > Class Template Referencefinal

A memory resource similar to std::pmr::unsynchronized_pool_resource, but optimized for node-based containers. More...

#include <pool.h>

Classes

struct  ListNode
 In-place linked list of the allocations, used for the freelist. More...
 

Public Member Functions

 PoolResource (std::size_t chunk_size_bytes)
 Construct a new PoolResource object which allocates the first chunk. More...
 
 PoolResource ()
 Construct a new Pool Resource object, defaults to 2^18=262144 chunk size. More...
 
 PoolResource (const PoolResource &)=delete
 Disable copy & move semantics, these are not supported for the resource. More...
 
PoolResourceoperator= (const PoolResource &)=delete
 
 PoolResource (PoolResource &&)=delete
 
PoolResourceoperator= (PoolResource &&)=delete
 
 ~PoolResource ()
 Deallocates all memory allocated associated with the memory resource. More...
 
void * Allocate (std::size_t bytes, std::size_t alignment)
 Allocates a block of bytes. More...
 
void Deallocate (void *p, std::size_t bytes, std::size_t alignment) noexcept
 Returns a block to the freelists, or deletes the block when it did not come from the chunks. More...
 
std::size_t NumAllocatedChunks () const
 Number of allocated chunks. More...
 
size_t ChunkSizeBytes () const
 Size in bytes to allocate per chunk, currently hardcoded to a fixed size. More...
 

Private Member Functions

void PlacementAddToList (void *p, ListNode *&node)
 Replaces node with placement constructed ListNode that points to the previous node. More...
 
void AllocateChunk ()
 Allocate one full memory chunk which will be used to carve out allocations. More...
 

Static Private Member Functions

static constexpr std::size_t NumElemAlignBytes (std::size_t bytes)
 How many multiple of ELEM_ALIGN_BYTES are necessary to fit bytes. More...
 
static constexpr bool IsFreeListUsable (std::size_t bytes, std::size_t alignment)
 True when it is possible to make use of the freelist. More...
 

Private Attributes

const size_t m_chunk_size_bytes
 Size in bytes to allocate per chunk. More...
 
std::list< std::byte * > m_allocated_chunks {}
 Contains all allocated pools of memory, used to free the data in the destructor. More...
 
std::array< ListNode *, MAX_BLOCK_SIZE_BYTES/ELEM_ALIGN_BYTES+1 > m_free_lists {}
 Single linked lists of all data that came from deallocating. More...
 
std::byte * m_available_memory_it = nullptr
 Points to the beginning of available memory for carving out allocations. More...
 
std::byte * m_available_memory_end = nullptr
 Points to the end of available memory for carving out allocations. More...
 

Static Private Attributes

static constexpr std::size_t ELEM_ALIGN_BYTES = std::max(alignof(ListNode), ALIGN_BYTES)
 Internal alignment value. More...
 

Friends

class PoolResourceTester
 Access to internals for testing purpose only. More...
 

Detailed Description

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
class PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >

A memory resource similar to std::pmr::unsynchronized_pool_resource, but optimized for node-based containers.

It has the following properties:

PoolResource is not thread-safe. It is intended to be used by PoolAllocator.

Template Parameters
MAX_BLOCK_SIZE_BYTESMaximum size to allocate with the pool. If larger sizes are requested, allocation falls back to new().
ALIGN_BYTESRequired alignment for the allocations.

An example: If you create a PoolResource<128, 8>(262144) and perform a bunch of allocations and deallocate 2 blocks with size 8 bytes, and 3 blocks with size 16, the members will look like this:

m_free_lists                         m_allocated_chunks
   ┌───┐                                ┌───┐  ┌────────────-------──────┐
   │   │  blocks                        │   ├─►│    262144 B             │
   │   │  ┌─────┐  ┌─────┐              └─┬─┘  └────────────-------──────┘
   │ 1 ├─►│ 8 B ├─►│ 8 B │                │
   │   │  └─────┘  └─────┘                :
   │   │                                  │
   │   │  ┌─────┐  ┌─────┐  ┌─────┐       ▼
   │ 2 ├─►│16 B ├─►│16 B ├─►│16 B │     ┌───┐  ┌─────────────────────────┐
   │   │  └─────┘  └─────┘  └─────┘     │   ├─►│          ▲              │ ▲
   │   │                                └───┘  └──────────┬──────────────┘ │
   │ . │                                                  │    m_available_memory_end
   │ . │                                         m_available_memory_it
   │ . │
   │   │
   │   │
   │16 │
   └───┘

Here m_free_lists[1] holds the 2 blocks of size 8 bytes, and m_free_lists[2] holds the 3 blocks of size 16. The blocks came from the data stored in the m_allocated_chunks list. Each chunk has bytes 262144. The last chunk has still some memory available for the blocks, and when m_available_memory_it is at the end, a new chunk will be allocated and added to the list.

Definition at line 70 of file pool.h.

Constructor & Destructor Documentation

◆ PoolResource() [1/4]

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::PoolResource ( std::size_t  chunk_size_bytes)
inlineexplicit

Construct a new PoolResource object which allocates the first chunk.

chunk_size_bytes will be rounded up to next multiple of ELEM_ALIGN_BYTES.

Definition at line 177 of file pool.h.

Here is the call graph for this function:

◆ PoolResource() [2/4]

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::PoolResource ( )
inline

Construct a new Pool Resource object, defaults to 2^18=262144 chunk size.

Definition at line 187 of file pool.h.

◆ PoolResource() [3/4]

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::PoolResource ( const PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES > &  )
delete

Disable copy & move semantics, these are not supported for the resource.

◆ PoolResource() [4/4]

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::PoolResource ( PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES > &&  )
delete

◆ ~PoolResource()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::~PoolResource ( )
inline

Deallocates all memory allocated associated with the memory resource.

Definition at line 200 of file pool.h.

Member Function Documentation

◆ Allocate()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
void* PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::Allocate ( std::size_t  bytes,
std::size_t  alignment 
)
inline

Allocates a block of bytes.

If possible the freelist is used, otherwise allocation is forwarded to ::operator new().

Definition at line 212 of file pool.h.

Here is the call graph for this function:

◆ AllocateChunk()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
void PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::AllocateChunk ( )
inlineprivate

Allocate one full memory chunk which will be used to carve out allocations.

Also puts any leftover bytes into the freelist.

Precondition: leftover bytes are either 0 or few enough to fit into a place in the freelist

Definition at line 153 of file pool.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ChunkSizeBytes()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
size_t PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::ChunkSizeBytes ( ) const
inline

Size in bytes to allocate per chunk, currently hardcoded to a fixed size.

Definition at line 265 of file pool.h.

Here is the caller graph for this function:

◆ Deallocate()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
void PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::Deallocate ( void *  p,
std::size_t  bytes,
std::size_t  alignment 
)
inlinenoexcept

Returns a block to the freelists, or deletes the block when it did not come from the chunks.

Definition at line 241 of file pool.h.

Here is the call graph for this function:

◆ IsFreeListUsable()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
static constexpr bool PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::IsFreeListUsable ( std::size_t  bytes,
std::size_t  alignment 
)
inlinestaticconstexprprivate

True when it is possible to make use of the freelist.

Definition at line 134 of file pool.h.

Here is the caller graph for this function:

◆ NumAllocatedChunks()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
std::size_t PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::NumAllocatedChunks ( ) const
inline

Number of allocated chunks.

Definition at line 257 of file pool.h.

◆ NumElemAlignBytes()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
static constexpr std::size_t PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::NumElemAlignBytes ( std::size_t  bytes)
inlinestaticconstexprprivate

How many multiple of ELEM_ALIGN_BYTES are necessary to fit bytes.

We use that result directly as an index into m_free_lists. Round up for the special case when bytes==0.

Definition at line 126 of file pool.h.

Here is the caller graph for this function:

◆ operator=() [1/2]

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
PoolResource& PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::operator= ( const PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES > &  )
delete

◆ operator=() [2/2]

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
PoolResource& PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::operator= ( PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES > &&  )
delete

◆ PlacementAddToList()

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
void PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::PlacementAddToList ( void *  p,
ListNode *&  node 
)
inlineprivate

Replaces node with placement constructed ListNode that points to the previous node.

Definition at line 142 of file pool.h.

Here is the caller graph for this function:

Friends And Related Function Documentation

◆ PoolResourceTester

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
friend class PoolResourceTester
friend

Access to internals for testing purpose only.

Definition at line 170 of file pool.h.

Member Data Documentation

◆ ELEM_ALIGN_BYTES

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
constexpr std::size_t PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::ELEM_ALIGN_BYTES = std::max(alignof(ListNode), ALIGN_BYTES)
staticconstexprprivate

Internal alignment value.

The larger of the requested ALIGN_BYTES and alignof(FreeList).

Definition at line 88 of file pool.h.

◆ m_allocated_chunks

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
std::list<std::byte*> PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::m_allocated_chunks {}
private

Contains all allocated pools of memory, used to free the data in the destructor.

Definition at line 101 of file pool.h.

◆ m_available_memory_end

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
std::byte* PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::m_available_memory_end = nullptr
private

Points to the end of available memory for carving out allocations.

That member variable is redundant, and is always equal to m_allocated_chunks.back() + m_chunk_size_bytes whenever it is accessed, but m_available_memory_end caches this for clarity and efficiency.

Definition at line 120 of file pool.h.

◆ m_available_memory_it

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
std::byte* PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::m_available_memory_it = nullptr
private

Points to the beginning of available memory for carving out allocations.

Definition at line 112 of file pool.h.

◆ m_chunk_size_bytes

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
const size_t PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::m_chunk_size_bytes
private

Size in bytes to allocate per chunk.

Definition at line 96 of file pool.h.

◆ m_free_lists

template<std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
std::array<ListNode*, MAX_BLOCK_SIZE_BYTES / ELEM_ALIGN_BYTES + 1> PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES >::m_free_lists {}
private

Single linked lists of all data that came from deallocating.

m_free_lists[n] will serve blocks of size n*ELEM_ALIGN_BYTES.

Definition at line 107 of file pool.h.


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