Memory Pools

A memory pool is a collection of fixed-sized memory blocks that support dynamic allocation. Allocation from a memory pool is fast and deterministic and since the blocks within a memory pool are fixed in size, they do not suffer from any sort of fragmentation. Memory pools are the preferred method when needing to perform dynamic allocation/deallocation from within interrupt service routines (ISR).

Basic Usage

When creating a memory pool, a region of memory is provided that will represent the individual blocks within the pool. The memory blocks can represent any type of data. The snippet below uses a structure to define an application-specific object.

#include "Kernel/kernel_pool.h"
#include <assert.h>

/* A custom application-defined object */
typedef struct MYOBJECT {
    UINT32 value1;
    UINT32 value2;
} MYOBJECT;

static MYOBJECT myobjects[10];              /* Allocate the memory to be used by the pool */
static POOL pool1;                          /* Allocate the memory pool */


/* Application Initialization */
void APP_Initialize(void)
{
    STATUS status;


    status = POOL_Create(&pool,             /* Create the memory pool */
                         objects,           /* A pointer to the memory managed by the pool */
                         sizeof(MYOBJECT),  /* The size of each block */
                         10);               /* The total number of blocks */

    assert(status == SUCCESS);
}

A block (or application-defined object) can be allocated from a pool at anytime, from any context, including an ISR. When allocating, the maximum amount of time is specified to wait for a block to become available. If allocating from an ISR, the timeout value is ignored since an ISR cannot be blocked.

MYOBJECT* obj;

obj = (MYOBJECT*)POOL_Alloc(&pool,      /* Attempt to allocate a block from the pool */
                            INFINITE);  /* Maximum amount of time to wait for a free block */

if (obj) {                              /* Was the block successfully allocated? */
		
    obj->value1 = 1;                    /* Use the allocated memory */
    obj->value2 = 0;

    POOL_Free(&pool, obj);              /* Return the memory back to the pool */
}

API Reference

STATUS POOL_Create(POOL* pool, const CHAR* name, void* mem, UINT32 blksize, UINT32 nblks)
Creates and initializes a fixed-sized block memory pool.
PARAMETERS
pool A pointer to a caller allocated memory pool to be initialized.
name A pointer to a NULL terminated string that represents a name for the pool
mem A pointer to a caller allocated region of memory to be managed by the pool.
blksize The size in bytes for each block contained within the memory pool. Must be at least the size of an address field within the target MCU. (i.e. 4 bytes for a 32-bit MCU)
nblks The total number of blocks for the memory pool. (Must be at least one)
RETURNS
SUCCESS The memory pool was created and initialized.
ERR_NULLREFERENCE The argument 'pool' or 'mem' was found to be NULL.
ERR_INVALIDCONTEXT This operation is not supported from the context of an interrupt service routine (ISR).
ERR_INVALIDARGUMENT The argument 'blksize' or 'nblks' was invalid.
ERR_ALREADYINITIALIZED The specified pool has already been created and initialized.
REMARKS
The buffer memory must be aligned on an pointer sized word boundry (i.e. 4 bytes for 32-bit).
Ensure that blksize is at least as large as sizeof(void*) (i.e. 4 bytes for 32-bit).
STATUS POOL_Destroy(POOL* pool)
Destroys and removes a memory pool from the kernel. Any threads that are waiting upon the memory pool will be released with the ERR_DESTROYED status code.
PARAMETERS
pool A pointer to the memory pool to be destroyed.
RETURNS
SUCCESS The memory pool was destroyed and removed from the kernel.
ERR_NULLREFERENCE The argument 'pool' was found to be NULL.
ERR_INVALIDCONTEXT This operation is not supported from the context of an interrupt service routine (ISR).
ERR_INVALIDARGUMENT The argument 'blksize' or 'nblks' was invalid.
ERR_NOTINITIALIZED The specified pool has not been created or initialized.
void* POOL_Alloc(POOL* pool, UINT32 timeout)
Allocates and returns a block of memory from a memory pool.
PARAMETERS
pool A pointer to the memory pool in which to allocate and return a block of memory.
timeout The maximum amount of time, in kernel ticks, to wait for a block to become available if the pool is currently empty. Use '0' to return immediately without waiting. Use INFINITE to wait indefinitely.
RETURNS
A non-zero pointer to the block of memory that has been allocated from the given pool upon success; otherwise NULL on any error.
void* POOL_Calloc(POOL* pool, UINT32 timeout)
Allocates and returns a block of memory from a memory pool that has been cleared (zero initialized).
PARAMETERS
pool A pointer to the memory pool in which to allocate and return a block of memory.
timeout The maximum amount of time, in kernel ticks, to wait for a block to become available if the pool is currently empty. Use '0' to return immediately without waiting. Use INFINITE to wait indefinitely.
RETURNS
A non-zero pointer to the block of memory that has been allocated from the given pool upon success; otherwise NULL on any error.
STATUS POOL_Free(POOL* pool, void* blk)
Returns a previously allocated block of memory back to a memory pool.
PARAMETERS
pool A pointer to the memory pool to receive the block.
blk A pointer to the block of memory to be returned to the specified pool.
RETURNS
SUCCESS The block was returned to the specified memory pool.
ERR_NULLREFERENCE The argument 'pool' or 'blk' was found to be NULL.
ERR_NOTINITIALIZED The specified pool has not been created or initialized.
REMARKS
Ensure the block was allocated from the specified pool and not to free the same block multiple times as there are no guards for these scenarios for the sake of efficiency.
UINT32 POOL_FreeCount(POOL* pool)
Returns the current number of available unallocated blocks remaining within a memory pool.
PARAMETERS
pool A pointer to the target memory pool in which to return a available block count.
RETURNS
The number of available blocks remaining in the specified memory pool.
UINT32 POOL_BlockSize(POOL* pool)
Returns the size in bytes for each block within a memory pool.
PARAMETERS
pool A pointer to the target memory pool in which to return the block size.
RETURNS
The size in bytes of each block within the specified pool.