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;
The next order of business is to allocate the memory used by the memory
pool. This memory can either be statically allocated (i.e. a global
variable) or dynamically allocated (i.e. from the heap). When
determining the amount of memory required for the memory pool, simply
multiplying the number of blocks by the size of each block is not
sufficient as the OS may have alignment requirements. The alignment size
definition is named OS_ALIGNMENT
and can be found in os_arch.h as
it is architecture specific. The memory block alignment is usually for
efficiency but may be due to other reasons. Generally, blocks are
aligned on 32-bit boundaries. Note that memory blocks must also be of
sufficient size to hold a list pointer as this is needed to chain memory
blocks on the free list.
In order to simplify this for the user two macros have been provided:
c:macro: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)];
Now that the memory pool has been defined as well as the memory
required for the memory blocks which make up the pool the user needs to
initialize the memory pool by calling os_mempool_init`()
.
os_mempool_init(&my_pool, NUM_BLOCKS, BLOCK_SIZE, my_memory_buffer,
"MyPool");
Once the memory pool has been initialized the developer can allocate
memory blocks from the pool by calling os_memblock_get()
. When the
memory block is no longer needed the memory can be freed by calling
os_memblock_put()
.
API¶
-
typedef os_error_t os_mempool_put_fn(struct os_mempool_ext *ome, void *data, void *arg)¶
Block put callback function.
If configured, this callback gets executed whenever a block is freed to the corresponding extended mempool. Note: The os_memblock_put() function calls this callback instead of freeing the block itself. Therefore, it is the callback’s responsibility to free the block via a call to os_memblock_put_from_cb().
- Param ome:
The extended mempool that a block is being freed back to.
- Param data:
The block being freed.
- Param arg:
Optional argument configured along with the callback.
- Return:
Indicates whether the block was successfully freed. A non-zero value should only be returned if the block was not successfully released back to its pool.
-
typedef uint32_t os_membuf_t¶
-
struct os_mempool *os_mempool_info_get_next(struct os_mempool*, struct os_mempool_info*)¶
Get information about the next system memory pool.
- Parameters:
mempool – The current memory pool, or NULL if starting iteration.
info – A pointer to the structure to return memory pool information into.
- Returns:
The next memory pool in the list to get information about, or NULL when at the last memory pool.
-
os_error_t os_mempool_init(struct os_mempool *mp, uint16_t blocks, uint32_t block_size, void *membuf, char *name)¶
Initialize a memory pool.
- Parameters:
mp – Pointer to a pointer to a mempool
blocks – The number of blocks in the pool
blocks_size – The size of the block, in bytes.
membuf – Pointer to memory to contain blocks.
name – Name of the pool.
- Returns:
os_error_t
-
os_error_t os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks, uint32_t block_size, void *membuf, char *name)¶
Initializes an extended memory pool.
Extended attributes (e.g., callbacks) are not specified when this function is called; they are assigned manually after initialization.
- Parameters:
mpe – The extended memory pool to initialize.
blocks – The number of blocks in the pool.
block_size – The size of each block, in bytes.
membuf – Pointer to memory to contain blocks.
name – Name of the pool.
- Returns:
os_error_t
-
os_error_t os_mempool_unregister(struct os_mempool *mp)¶
Removes the specified mempool from the list of initialized mempools.
- Parameters:
mp – The mempool to unregister.
- Returns:
0 on success; OS_INVALID_PARM if the mempool is not registered.
-
os_error_t os_mempool_clear(struct os_mempool *mp)¶
Clears a memory pool.
- Parameters:
mp – The mempool to clear.
- Returns:
os_error_t
-
bool os_mempool_is_sane(const struct os_mempool *mp)¶
Performs an integrity check of the specified mempool.
This function attempts to detect memory corruption in the specified memory pool.
- Parameters:
mp – The mempool to check.
- Returns:
true if the memory pool passes the integrity check; false if the memory pool is corrupt.
-
int os_memblock_from(const struct os_mempool *mp, const void *block_addr)¶
Checks if a memory block was allocated from the specified mempool.
- Parameters:
mp – The mempool to check as parent.
block_addr – The memory block to check as child.
- Returns:
0 if the block does not belong to the mempool; 1 if the block does belong to the mempool.
-
void *os_memblock_get(struct os_mempool *mp)¶
Get a memory block from a memory pool.
- Parameters:
mp – Pointer to the memory pool
- Returns:
void* Pointer to block if available; NULL otherwise
-
os_error_t os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr)¶
Puts the memory block back into the pool, ignoring the put callback, if any.
This function should only be called from a put callback to free a block without causing infinite recursion.
- Parameters:
mp – Pointer to memory pool
block_addr – Pointer to memory block
- Returns:
os_error_t
-
os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr)¶
Puts the memory block back into the pool.
- Parameters:
mp – Pointer to memory pool
block_addr – Pointer to memory block
- Returns:
os_error_t
-
OS_MEMPOOL_F_EXT¶
Indicates an extended mempool.
Address can be safely cast to (struct os_mempool_ext *).
-
OS_MEMPOOL_INFO_NAME_LEN¶
-
OS_MEMPOOL_BLOCK_SZ(sz)¶
-
OS_MEMPOOL_SIZE(n, blksize)¶
-
OS_MEMPOOL_BYTES(n, blksize)¶
Calculates the number of bytes required to initialize a memory pool.
-
struct os_memblock¶
- #include <os_mempool.h>
A memory block structure.
This simply contains a pointer to the free list chain and is only used when the block is on the free list. When the block has been removed from the free list the entire memory block is usable by the caller.
-
struct os_mempool¶
- #include <os_mempool.h>
Memory pool.
Public Members
-
uint32_t mp_block_size¶
Size of the memory blocks, in bytes.
-
uint16_t mp_num_blocks¶
The number of memory blocks.
-
uint16_t mp_num_free¶
The number of free blocks left.
-
uint16_t mp_min_free¶
The lowest number of free blocks seen.
-
uint8_t mp_flags¶
Bitmap of OS_MEMPOOL_F_[…] values.
-
uint32_t mp_membuf_addr¶
Address of memory buffer used by pool.
-
char *name¶
Name for memory block.
-
uint32_t mp_block_size¶
-
struct os_mempool_ext¶
- #include <os_mempool.h>
-
struct os_mempool_info¶
- #include <os_mempool.h>
Information describing a memory pool, used to return OS information to the management layer.
Public Members
-
int omi_block_size¶
Size of the memory blocks in the pool.
-
int omi_num_blocks¶
Number of memory blocks in the pool.
-
int omi_num_free¶
Number of free memory blocks.
-
int omi_min_free¶
Minimum number of free memory blocks ever.
-
char omi_name[OS_MEMPOOL_INFO_NAME_LEN]¶
Name of the memory pool.
-
int omi_block_size¶