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.
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");
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]; };
Element | Description |
---|---|
mp_block_size | Size 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_blocks | Number of memory blocks in the pool |
mp_num_free | Number of free blocks left |
mp_min_free | Lowest number of free blocks seen |
mp_membuf_addr | The address of the memory block. This is used to check that a valid memory block is being freed. |
mp_list | List pointer to chain memory pools so they can be displayed by newt tools |
SLIST_HEAD(,os_memblock) | List pointer to chain free memory blocks |
name | Name for the memory block |
The functions/macros available in mem_pool are:
Function | Description |
---|---|
os_memblock_get | Allocate an element from the memory pool. |
os_mempool_init | Initializes the memory pool. |
os_memblock_put | Releases previously allocated element back to the pool. |
os_mempool_info_get_next | Retrieves memory pool information for the next memory pool. |
OS_MEMPOOL_BYTES | Calculates how many bytes of memory is used by n number of elements, when individual element size is blksize bytes. |
OS_MEMPOOL_SIZE | Calculates the number of os_membuf_t elements used by n blocks of size blksize bytes. |