Memory Pools

A memory pool is a collection of fixed sized elements called memory blocks. Generally, memory pools are used when the developer wants to allocate a certain amount of memory to a given feature. Unlike the heap, where a code module is at the mercy of other code modules to insure there is sufficient memory, memory pools can insure sufficient memory allocation.

Description

In order to create a memory pool the developer needs to do a few things. The first task is to define the memory pool itself. This is a data structure which contains information about the pool itself (i.e. number of blocks, size of the blocks, etc).

struct os_mempool my_pool;

In order to simplify this for the user two macros have been provided: OS_MEMPOOL_BYTES(n, blksize) and OS_MEMPOOL_SIZE(n, blksize). The first macro returns the number of bytes needed for the memory pool while the second returns the number of os_membuf_t elements required by the memory pool. The os_membuf_t type is used to guarantee that the memory buffer used by the memory pool is aligned on the correct boundary.

Here are some examples. Note that if a custom malloc implementation is used it must guarantee that the memory buffer used by the pool is allocated on the correct boundary (i.e. OS_ALIGNMENT).

void *my_memory_buffer;
my_memory_buffer = malloc(OS_MEMPOOL_BYTES(NUM_BLOCKS, BLOCK_SIZE));
os_membuf_t my_memory_buffer[OS_MEMPOOL_SIZE(NUM_BLOCKS, BLOCK_SIZE)];
os_mempool_init(&my_pool, NUM_BLOCKS, BLOCK_SIZE, my_memory_buffer,
                         "MyPool");

Data structures

struct os_mempool {
    int mp_block_size;
    int mp_num_blocks;
    int mp_num_free;
    int mp_min_free;
    uint32_t mp_membuf_addr;
    STAILQ_ENTRY(os_mempool) mp_list;    
    SLIST_HEAD(,os_memblock);
    char *name;
};

struct os_mempool_info {
    int omi_block_size;
    int omi_num_blocks;
    int omi_num_free;
    int omi_min_free;
    char omi_name[OS_MEMPOOL_INFO_NAME_LEN];
};

ElementDescription
mp_block_sizeSize of the memory blocks, in bytes. This is not the actual number of bytes used by each block; it is the requested size of each block. The actual memory block size will be aligned to OS_ALIGNMENT bytes
mp_num_blocksNumber of memory blocks in the pool
mp_num_freeNumber of free blocks left
mp_min_freeLowest number of free blocks seen
mp_membuf_addrThe address of the memory block. This is used to check that a valid memory block is being freed.
mp_listList pointer to chain memory pools so they can be displayed by newt tools
SLIST_HEAD(,os_memblock)List pointer to chain free memory blocks
nameName for the memory block

List of Functions/Macros

The functions/macros available in mem_pool are:

FunctionDescription
os_memblock_getAllocate an element from the memory pool.
os_mempool_initInitializes the memory pool.
os_memblock_putReleases previously allocated element back to the pool.
os_mempool_info_get_nextRetrieves memory pool information for the next memory pool.
OS_MEMPOOL_BYTESCalculates how many bytes of memory is used by n number of elements, when individual element size is blksize bytes.
OS_MEMPOOL_SIZECalculates the number of os_membuf_t elements used by n blocks of size blksize bytes.