Veritable Lasagna
An Allocator & Data Structure Library for C.
Loading...
Searching...
No Matches
vl_async_pool.h File Reference
#include "vl_atomic.h"
#include "vl_atomic_ptr.h"
+ Include dependency graph for vl_async_pool.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  vl_async_pool
 A Non-Blocking Atomic (/Asynchronous) Memory Pool. More...
 

Functions

void vlAsyncPoolInit (vl_async_pool *pool, vl_uint16_t elementSize)
 Initializes the specified async pool.
 
void vlAsyncPoolFree (vl_async_pool *pool)
 Frees the specified async pool, and all associated memory.
 
vl_async_poolvlAsyncPoolNew (vl_uint16_t elementSize)
 Allocates and initializes a new async pool.
 
void vlAsyncPoolDelete (vl_async_pool *pool)
 Deinitializes and deletes the specified async pool, and all associated memory.
 
void vlAsyncPoolReset (vl_async_pool *pool)
 Resets the specified async pool, returning it to its state when it was first initialized.
 
void vlAsyncPoolClear (vl_async_pool *pool)
 Resets the state of all blocks and the pool, retaining memory but invalidating taken elements.
 
void * vlAsyncPoolTake (vl_async_pool *pool)
 Takes an element from the specified async pool.
 
void vlAsyncPoolReturn (vl_async_pool *pool, void *element)
 Returns an element to the specified async pool.
 

Variables

const vl_ularge_t VL_ASYNC_POOL_BLOCK_ALIGNMENT
 Byte-level alignment of individual vlAsyncPool memory blocks.
 
const vl_ularge_t VL_ASYNC_POOL_NODE_ALIGNMENT
 Byte-level alignment of individual vlAsyncPool element nodes.
 

Data Structure Documentation

◆ vl_async_pool

struct vl_async_pool

A Non-Blocking Atomic (/Asynchronous) Memory Pool.

Represents a memory pool that works in elements of a fixed size. This requires notably more time and space overhead in comparison to vl_linear_pool and vl_fixed_pool, but offers the benefit of thread safe taking and returning.

See also
vl_linear_pool
vl_fixed_pool

This structure is implemented almost entirely using atomic primitives. The action of taking/returning elements to/from this pool are entirely atomic, and well-suited for multi-threaded computing.

Blocks of memory are allocated with a size following geometric growth up to a min/max of 2^(4/16) elements, after which they have reached their maximum size and further allocated blocks continue to have that size.

This structure is non-blocking; no single operation will block execution. All threads operating on this pool will continue to make progress towards their individual operations. Using Compare-And-Swap (CAS), failed operations are re-tried until their success (the "wait").

Other pool-wide operations (clearing, resetting) require the user to bring their own explicit synchronization methods. Similarly, element-level synchronization and thread-safety also requires user-end synchronization, if applicable.

Taken elements will never be moved by the pool structure algorithm, but may be invalidated via clearing, resetting, freeing, or deleting the pool.

Returned nodes are pushed onto a Treiber stack for later reuse.

See also
https://en.wikipedia.org/wiki/Treiber_stack

The ABA problem is prevented through the use of pointer tagging.

See also
vl_tagged_ptr
https://en.wikipedia.org/wiki/ABA_problem
Note
This structure is non-blocking, but is not wait-free.
+ Collaboration diagram for vl_async_pool:
Data Fields
vl_atomic_bool_t allocatingFlag
vl_uint16_t elementSize
vl_atomic_uint32_t freeLength
vl_atomic_ptr freeStack
vl_uint16_t nodeSize
vl_atomic_ptr primaryBlock
vl_atomic_uint16_t totalBlocks

Function Documentation

◆ vlAsyncPoolClear()

void vlAsyncPoolClear ( vl_async_pool * pool)

Resets the state of all blocks and the pool, retaining memory but invalidating taken elements.

This does not free any associated memory.

Warning
This will invalidate all elements taken prior to this call. Manual synchronization is highly recommended.
Parameters
poolpointer to the async pool to clear
+ Here is the caller graph for this function:

◆ vlAsyncPoolDelete()

void vlAsyncPoolDelete ( vl_async_pool * pool)

Deinitializes and deletes the specified async pool, and all associated memory.

The specified pool must have been initialized via vlAsyncPoolNew.

Warning
This will invalidate all elements taken prior to this call. Manual synchronization is highly recommended.
See also
vlAsyncPoolNew
Parameters
poolpointer to async pool to delete
+ Here is the call graph for this function:

◆ vlAsyncPoolFree()

void vlAsyncPoolFree ( vl_async_pool * pool)

Frees the specified async pool, and all associated memory.

The pool must have been initialized via vlAsyncPoolInit.

Warning
This will invalidate all elements taken prior to this call. Manual synchronization is highly recommended.
See also
vlAsyncPoolInit
Parameters
pool
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ vlAsyncPoolInit()

void vlAsyncPoolInit ( vl_async_pool * pool,
vl_uint16_t elementSize )

Initializes the specified async pool.

The pool must be later freed via vlAsyncPoolFree.

See also
vlAsyncPoolFree
Parameters
poolpointer to pool that will be initialized
elementSizetotal size of a single element, in bytes.
+ Here is the caller graph for this function:

◆ vlAsyncPoolNew()

vl_async_pool * vlAsyncPoolNew ( vl_uint16_t elementSize)

Allocates and initializes a new async pool.

The specified pool must later be deleted via vlAsyncPoolDelete.

See also
vlAsyncPoolDelete
Parameters
elementSize
Returns
pointer to newly allocated async pool.
+ Here is the call graph for this function:

◆ vlAsyncPoolReset()

void vlAsyncPoolReset ( vl_async_pool * pool)

Resets the specified async pool, returning it to its state when it was first initialized.

This frees all allocated blocks of nodes up to the first.

Warning
This will invalidate all elements taken prior to this call. Manual synchronization is highly recommended.
Parameters
poolpointer to the async pool to reset
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ vlAsyncPoolReturn()

void vlAsyncPoolReturn ( vl_async_pool * pool,
void * element )

Returns an element to the specified async pool.

Parameters
poolpointer to async pool
elementpointer to returned element
Complexity of O(1) constant.
+ Here is the caller graph for this function:

◆ vlAsyncPoolTake()

void * vlAsyncPoolTake ( vl_async_pool * pool)

Takes an element from the specified async pool.

Parameters
poolpointer to async pool
Complexity of O(1) constant.
Returns
pointer to taken element
+ Here is the caller graph for this function:

Variable Documentation

◆ VL_ASYNC_POOL_BLOCK_ALIGNMENT

const vl_ularge_t VL_ASYNC_POOL_BLOCK_ALIGNMENT
extern

Byte-level alignment of individual vlAsyncPool memory blocks.

◆ VL_ASYNC_POOL_NODE_ALIGNMENT

const vl_ularge_t VL_ASYNC_POOL_NODE_ALIGNMENT
extern

Byte-level alignment of individual vlAsyncPool element nodes.