pbr-cpp-memory-pool 1.1.2
Fixed-block-size O(1) memory pool — C++17 with an ANSI C public surface
Loading...
Searching...
No Matches
memory_pool.h File Reference

Public C API for the pbr-cpp-memory-pool fixed-block-size allocator. More...

#include <stddef.h>

Go to the source code of this file.

Macros

#define PBR_MEMORY_POOL_THREAD_SAFETY_NONE   0
 
#define PBR_MEMORY_POOL_THREAD_SAFETY_MUTEX   1
 
#define PBR_MEMORY_POOL_THREAD_SAFETY_LOCKFREE   2
 
#define PBR_MEMORY_POOL_THREAD_SAFETY   PBR_MEMORY_POOL_THREAD_SAFETY_NONE
 

Typedefs

typedef struct memory_pool memory_pool_t
 Opaque handle to a memory pool instance.
 

Functions

memory_pool_tmemory_pool_create (size_t block_size, size_t block_count)
 Create a memory pool able to vend block_count blocks of block_size bytes each.
 
memory_pool_tmemory_pool_create_dynamic (size_t block_size, size_t block_count, size_t growth_factor)
 Create a memory pool in dynamic-growth mode (spec section 2.2): when exhausted it acquires a new contiguous chunk so capacity grows geometrically, instead of failing.
 
void * memory_pool_alloc (memory_pool_t *pool)
 Allocate one block from pool in O(1).
 
void memory_pool_free (memory_pool_t *pool, void *block)
 Return a previously allocated block to pool in O(1).
 
void memory_pool_destroy (memory_pool_t *pool)
 Destroy pool and release every byte of pre-allocated backing storage back to the operating system, per spec section 3.1 and ADR-0009 §7.
 
size_t memory_pool_metadata_bytes (const memory_pool_t *pool)
 Report the per-pool metadata overhead in bytes (spec section 3.2 / ADR-0015).
 
size_t memory_pool_block_size (const memory_pool_t *pool)
 Report the configured per-block size of pool in bytes (ADR-0018 §3).
 
size_t memory_pool_growths (const memory_pool_t *pool)
 Report how many times pool has grown — i.e.
 
const void * memory_pool_debug_free_list_head (const memory_pool_t *pool)
 Diagnostics — return the head of pool's implicit free list (ADR-0019 §2).
 
const void * memory_pool_debug_free_list_next (const memory_pool_t *pool, const void *current)
 Diagnostics — given a free slot current obtained from memory_pool_debug_free_list_head or a previous call to this function, return the next free slot in the implicit free list, or NULL at the end of the list (ADR-0019 §2).
 
size_t memory_pool_debug_free_count (const memory_pool_t *pool)
 Diagnostics — count the free slots currently in pool's free list by walking it in O(free_count) (ADR-0019 §2).
 

Detailed Description

Public C API for the pbr-cpp-memory-pool fixed-block-size allocator.

This header is the C-language contract surface defined by spec section 5. It is held to ANSI C (C89) compatibility per ADR-0005 section 3; a CI job (ROADMAP item 1.10) compiles it under -std=c89 -pedantic -Werror and -std=c99 -pedantic -Werror. Avoid C99-or-later constructs (inline, designated initialisers, _Bool, single-line // comments outside of other headers, mixed declarations and code) in this file.

Implementations of every function declared here arrive in Milestone 2; during Milestone 1 the library is a header-only INTERFACE target so any consumer that calls these functions will get a link error until then.

Definition in file memory_pool.h.

Macro Definition Documentation

◆ PBR_MEMORY_POOL_THREAD_SAFETY_NONE

#define PBR_MEMORY_POOL_THREAD_SAFETY_NONE   0

Definition at line 63 of file memory_pool.h.

◆ PBR_MEMORY_POOL_THREAD_SAFETY_MUTEX

#define PBR_MEMORY_POOL_THREAD_SAFETY_MUTEX   1

Definition at line 64 of file memory_pool.h.

◆ PBR_MEMORY_POOL_THREAD_SAFETY_LOCKFREE

#define PBR_MEMORY_POOL_THREAD_SAFETY_LOCKFREE   2

Definition at line 65 of file memory_pool.h.

◆ PBR_MEMORY_POOL_THREAD_SAFETY

#define PBR_MEMORY_POOL_THREAD_SAFETY   PBR_MEMORY_POOL_THREAD_SAFETY_NONE

Definition at line 67 of file memory_pool.h.

Typedef Documentation

◆ memory_pool_t

typedef struct memory_pool memory_pool_t

Opaque handle to a memory pool instance.

Definition at line 82 of file memory_pool.h.

Function Documentation

◆ memory_pool_create()

memory_pool_t * memory_pool_create ( size_t  block_size,
size_t  block_count 
)

Create a memory pool able to vend block_count blocks of block_size bytes each.

Memory is allocated contiguously and pre-populated as a free list per spec section 4. The full layout and validation contract is recorded in ADR-0009 (docs/adr/0009-...); the summary below is binding.

Parameters
block_sizeSize of each block in bytes. ADR-0009 §2 requires all of:
  • block_size > 0
  • block_size >= sizeof(void*) (the free-list link must fit in a free slot)
  • block_size is a multiple of alignof(max_align_t) (drop-in malloc-parity alignment, ADR-0009 §5). Any violation makes the call return NULL; the implementation never silently rounds up.
block_countNumber of blocks the pool can vend. Must be greater than zero. ADR-0009 §3 additionally requires that block_size * block_count not overflow size_t; overflow is treated as an argument-validation failure and returns NULL.
Returns
Pointer to the newly created pool, or NULL on any precondition violation or on backing-storage allocation failure. Allocation failure inside the implementation never propagates as a C++ exception across this C ABI boundary (ADR-0005 §3 + ADR-0009 §7).

◆ memory_pool_create_dynamic()

memory_pool_t * memory_pool_create_dynamic ( size_t  block_size,
size_t  block_count,
size_t  growth_factor 
)

Create a memory pool in dynamic-growth mode (spec section 2.2): when exhausted it acquires a new contiguous chunk so capacity grows geometrically, instead of failing.

The full policy is recorded in ADR-0022 / ADR-0024; the summary below is binding.

Parameters
block_sizeSame contract as memory_pool_create (ADR-0009 section 2).
block_countInitial block count; same contract (ADR-0009 section 3).
growth_factorGeometric factor: on exhaustion the total capacity is multiplied by this factor (the new chunk supplies current_total * (growth_factor - 1) blocks). Must be at least 2; a smaller value is an argument-validation failure and returns NULL.
Returns
Pointer to the new dynamic pool, or NULL on any precondition violation, on backing-storage allocation failure, or — in a library built with the lock-free thread-safety policy — always, because dynamic growth is not supported there (ADR-0024 section 2); a lock-free build supports only fixed pools via memory_pool_create. Allocation failure never propagates as a C++ exception across this C ABI boundary.

◆ memory_pool_alloc()

void * memory_pool_alloc ( memory_pool_t pool)

Allocate one block from pool in O(1).

Parameters
poolPool returned by memory_pool_create. Passing NULL is defined and returns NULL.
Returns
Pointer to a block of block_size bytes, or NULL when the pool is exhausted (fixed-size mode) or, post-Milestone 5, when dynamic growth itself fails. The pointer is aligned to alignof(max_align_t) — drop-in parity with malloc per ADR-0009 §5.

◆ memory_pool_free()

void memory_pool_free ( memory_pool_t pool,
void *  block 
)

Return a previously allocated block to pool in O(1).

Per ADR-0012, the function is a defined no-op in three cases that the caller might pass by mistake:

  • pool is NULL;
  • block is NULL;
  • block is a foreign pointer — outside pool's backing buffer or in-range but not aligned to a slot boundary.

Detection of the foreign-pointer case is an O(1) range + alignment check against the pool's backing extents (ADR-0009 §6 fields). The pool state is bit-identical before and after a no-op call. Note that the policy does NOT detect double-free on a legitimately-in-range, already-on-the-free-list pointer; that case remains undefined behaviour. The optional InstrumentedPool Decorator (Milestone 6) counts deallocation calls but does not detect a double-free either — it cannot distinguish one from a legitimate free — so it must not be relied on to make a double-free safe.

Parameters
poolPool the block originally came from.
blockBlock to release, or NULL, or a foreign pointer.

◆ memory_pool_destroy()

void memory_pool_destroy ( memory_pool_t pool)

Destroy pool and release every byte of pre-allocated backing storage back to the operating system, per spec section 3.1 and ADR-0009 §7.

The backing buffer is released through the matching aligned ::operator delete overload of the C++17 ::operator new(size, std::align_val_t) used at creation; the metadata struct is released via the matching plain delete. Passing NULL is a no-op. After this call, pool must not be reused.

Parameters
poolPool to destroy, or NULL.

◆ memory_pool_metadata_bytes()

size_t memory_pool_metadata_bytes ( const memory_pool_t pool)

Report the per-pool metadata overhead in bytes (spec section 3.2 / ADR-0015).

Returns the size of pool-internal bookkeeping — currently the struct memory_pool itself, per ADR-0009 section 6. The value is O(1) in both block_count and block_size: a pool with one million blocks reports the same number as a pool with one. Per-block metadata is zero by construction (implicit free list, ADR-0009 section 1).

The CI build matrix gates sizeof(struct memory_pool) to a 128-byte upper bound through a static_assert in the implementation file (ADR-0015 section 3); this function reports the value at runtime so test code and production diagnostics can verify the budget against the same number that gates compile time.

Parameters
poolPool to inspect, or NULL.
Returns
Number of metadata bytes for pool, or 0 if pool is NULL.

◆ memory_pool_block_size()

size_t memory_pool_block_size ( const memory_pool_t pool)

Report the configured per-block size of pool in bytes (ADR-0018 §3).

Returns the block_size value pool was created with — the byte size of every block memory_pool_alloc vends. The value is fixed for the pool's lifetime and the call is O(1). This is the introspection companion to memory_pool_metadata_bytes; the STL allocator adapter (ADR-0018) uses it to decide whether a given object size fits in a single block before routing a request to the pool.

Parameters
poolPool to inspect, or NULL.
Returns
The pool's block_size in bytes, or 0 if pool is NULL.

◆ memory_pool_growths()

size_t memory_pool_growths ( const memory_pool_t pool)

Report how many times pool has grown — i.e.

acquired an overflow chunk in dynamic mode (spec section 2.2 / ADR-0024) — in O(1) (ADR-0026).

Always 0 for a fixed-mode pool and for a library built with the lock-free thread-safety policy (which does not support dynamic growth). The count is written only on the rare growth slow path, so reading it never touches the allocation hot path; the Observer (InstrumentedPool) uses it to detect a growth event after an allocation.

Parameters
poolPool to inspect, or NULL.
Returns
The number of growths, or 0 if pool is NULL.

◆ memory_pool_debug_free_list_head()

const void * memory_pool_debug_free_list_head ( const memory_pool_t pool)

Diagnostics — return the head of pool's implicit free list (ADR-0019 §2).

This is the address of the first free slot, or NULL when the pool is exhausted or pool is NULL. Read-only; never mutate the storage the returned pointer addresses.

Available only when PBR_MEMORY_POOL_DIAGNOSTICS is non-zero (the default in debug builds; opt-in in release builds). Intended for tests and diagnostics — the walk it begins is O(free_count).

Parameters
poolPool to inspect, or NULL.
Returns
Address of the first free slot, or NULL.

◆ memory_pool_debug_free_list_next()

const void * memory_pool_debug_free_list_next ( const memory_pool_t pool,
const void *  current 
)

Diagnostics — given a free slot current obtained from memory_pool_debug_free_list_head or a previous call to this function, return the next free slot in the implicit free list, or NULL at the end of the list (ADR-0019 §2).

The next-free link is read from inside current per the ADR-0009 §1 layout, which stays encapsulated in the implementation.

Parameters
poolPool the slot belongs to, or NULL (returns NULL).
currentA free slot from this pool's list, or NULL (returns NULL).
Returns
Address of the next free slot, or NULL at end of list.

◆ memory_pool_debug_free_count()

size_t memory_pool_debug_free_count ( const memory_pool_t pool)

Diagnostics — count the free slots currently in pool's free list by walking it in O(free_count) (ADR-0019 §2).

Equivalent to std::distance(begin, end) over the C++ FreeListView; the test suite cross-checks the two.

Parameters
poolPool to inspect, or NULL.
Returns
Number of free slots, or 0 when pool is NULL.