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().
- 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.
- Parameters
ome
: The extended mempool that a block is being freed back to.data
: The block being freed.arg
: Optional argument configured along with the callback.
-
struct os_mempool *
os_mempool_info_get_next
(struct os_mempool *mp, struct os_mempool_info *omi)¶ Get information about the next system memory pool.
- Return
The next memory pool in the list to get information about; NULL when at the last memory pool.
- Parameters
mp
: The current memory pool, or NULL if starting iteration.omi
: A pointer to the structure to return memory pool information into.
-
struct os_mempool *
os_mempool_get
(const char *mempool_name, struct os_mempool_info *info)¶ Get information system memory pool by name.
- Return
The memory pool found; NULL when there is no such memory pool.
- Parameters
mempool_name
: The name of mempool.info
: A pointer to the structure to return memory pool information into, can be NULL.
-
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.
- Return
0 on success; Non-zero error code on failure.
- Parameters
mp
: Pointer to a pointer to a mempoolblocks
: The number of blocks in the poolblock_size
: The size of the block, in bytes.membuf
: Pointer to memory to contain blocks.name
: Name of the pool.
-
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.
- Return
0 on success; Non-zero error code on failure.
- 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.
-
os_error_t
os_mempool_unregister
(struct os_mempool *mp)¶ Removes the specified mempool from the list of initialized mempools.
- Return
0 on success; OS_INVALID_PARM if the mempool is not registered.
- Parameters
mp
: The mempool to unregister.
-
os_error_t
os_mempool_clear
(struct os_mempool *mp)¶ Clears a memory pool.
- Return
0 on success; Non-zero error code on failure.
- Parameters
mp
: The mempool to clear.
-
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.
- Return
true if the memory pool passes the integrity check; false if the memory pool is corrupt.
- Parameters
mp
: The mempool to check.
-
int
os_memblock_from
(const struct os_mempool *mp, const void *block_addr)¶ Checks if a memory block was allocated from the specified mempool.
- Return
0 if the block does not belong to the mempool; 1 if the block does belong to the mempool.
- Parameters
mp
: The mempool to check as parent.block_addr
: The memory block to check as child.
-
void *
os_memblock_get
(struct os_mempool *mp)¶ Get a memory block from a memory pool.
- Return
Pointer to block if available; NULL otherwise
- Parameters
mp
: Pointer to the memory pool
-
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.
- Return
0 on success; Non-zero error code on failure.
- Parameters
mp
: Pointer to memory poolblock_addr
: Pointer to memory block
-
os_error_t
os_memblock_put
(struct os_mempool *mp, void *block_addr)¶ Puts the memory block back into the pool.
- Return
0 on success; Non-zero error code on failure.
- Parameters
mp
: Pointer to memory poolblock_addr
: Pointer to memory block
-
OS_MEMPOOL_F_EXT
¶ Indicates an extended mempool.
Address can be safely cast to (struct os_mempool_ext *).
-
OS_MEMPOOL_INFO_NAME_LEN
¶ Length of the name of memory pool.
-
OS_MEMPOOL_BLOCK_SZ
(sz)¶ Leave extra 4 bytes of guard area at the end.
-
OS_MEMPOOL_SIZE
(n, blksize)¶ The total size of a memory pool, including alignment.
-
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.
Public Functions
-
SLIST_ENTRY (os_memblock) mb_next
Next memory block in the list.
-
-
struct
os_mempool
¶ - #include <os_mempool.h>
Memory pool.
Public Functions
-
STAILQ_ENTRY (os_mempool) mp_list
Next memory pool in the list.
-
SLIST_HEAD (, os_memblock)
Head of the list of memory blocks.
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.
-
uintptr_t
mp_membuf_addr
¶ Address of memory buffer used by pool.
-
char *
name
¶ Name for memory block.
-
-
struct
os_mempool_ext
¶ - #include <os_mempool.h>
Extended memory pool.
Public Members
-
struct os_mempool
mpe_mp
¶ Standard memory pool.
-
os_mempool_put_fn *
mpe_put_cb
¶ Callback that is executed immediately when a block is freed.
-
void *
mpe_put_arg
¶ Optional argument passed to the callback function.
-
struct os_mempool
-
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