|
pbr-cpp-memory-pool 1.1.2
Fixed-block-size O(1) memory pool — C++17 with an ANSI C public surface
|
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_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_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. | |
| 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). | |
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.
| #define PBR_MEMORY_POOL_THREAD_SAFETY_NONE 0 |
Definition at line 63 of file memory_pool.h.
| #define PBR_MEMORY_POOL_THREAD_SAFETY_MUTEX 1 |
Definition at line 64 of file memory_pool.h.
| #define PBR_MEMORY_POOL_THREAD_SAFETY_LOCKFREE 2 |
Definition at line 65 of file memory_pool.h.
| #define PBR_MEMORY_POOL_THREAD_SAFETY PBR_MEMORY_POOL_THREAD_SAFETY_NONE |
Definition at line 67 of file memory_pool.h.
| typedef struct memory_pool memory_pool_t |
Opaque handle to a memory pool instance.
Definition at line 82 of file memory_pool.h.
| 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.
| block_size | Size of each block in bytes. ADR-0009 §2 requires all of:
|
| block_count | Number 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. |
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_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.
| block_size | Same contract as memory_pool_create (ADR-0009 section 2). |
| block_count | Initial block count; same contract (ADR-0009 section 3). |
| growth_factor | Geometric 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. |
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. | void * memory_pool_alloc | ( | memory_pool_t * | pool | ) |
Allocate one block from pool in O(1).
| pool | Pool returned by memory_pool_create. Passing NULL is defined and returns NULL. |
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. | 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.
| pool | Pool the block originally came from. |
| block | Block to release, or NULL, or a foreign pointer. |
| 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.
| pool | Pool to destroy, or NULL. |
| 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.
| pool | Pool to inspect, or NULL. |
pool, or 0 if pool is NULL. | 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.
| pool | Pool to inspect, or NULL. |
block_size in bytes, or 0 if pool is NULL. | 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.
| pool | Pool to inspect, or NULL. |
pool is NULL. | 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).
| pool | Pool to inspect, or NULL. |
NULL. | 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.
| pool | Pool the slot belongs to, or NULL (returns NULL). |
| current | A free slot from this pool's list, or NULL (returns NULL). |
NULL at end of list. | 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.
| pool | Pool to inspect, or NULL. |
pool is NULL.