mempool: add API for malloc semantics
This works like k_malloc() but allows the user to designate a specific memory pool to use instead of the kernel heap. Test coverage provided by existing tests for k_malloc(), which is now derived from this API. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
c8010e4877
commit
a2480bd472
3 changed files with 56 additions and 33 deletions
|
@ -151,10 +151,15 @@ since that is the closest matching size supported by the memory pool.
|
||||||
printf("Memory allocation time-out");
|
printf("Memory allocation time-out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Memory blocks may also be allocated with :cpp:func:`malloc()`-like semantics
|
||||||
|
using :cpp:func:`k_mem_pool_malloc()`. Such allocations must be freed with
|
||||||
|
:cpp:func:`k_free()`.
|
||||||
|
|
||||||
Releasing a Memory Block
|
Releasing a Memory Block
|
||||||
========================
|
========================
|
||||||
|
|
||||||
A memory block is released by calling :cpp:func:`k_mem_pool_free()`.
|
A memory block is released by calling either :cpp:func:`k_mem_pool_free()`
|
||||||
|
or :cpp:func:`k_free()`, depending on how it was allocated.
|
||||||
|
|
||||||
The following code builds on the example above, and allocates a 75 byte
|
The following code builds on the example above, and allocates a 75 byte
|
||||||
memory block, then releases it once it is no longer needed. (A 256 byte
|
memory block, then releases it once it is no longer needed. (A 256 byte
|
||||||
|
@ -184,3 +189,5 @@ The following memory pool APIs are provided by :file:`kernel.h`:
|
||||||
* :c:macro:`K_MEM_POOL_DEFINE`
|
* :c:macro:`K_MEM_POOL_DEFINE`
|
||||||
* :cpp:func:`k_mem_pool_alloc()`
|
* :cpp:func:`k_mem_pool_alloc()`
|
||||||
* :cpp:func:`k_mem_pool_free()`
|
* :cpp:func:`k_mem_pool_free()`
|
||||||
|
* :cpp:func:`k_mem_pool_malloc()`
|
||||||
|
* :cpp:func:`k_free()`
|
||||||
|
|
|
@ -3652,6 +3652,17 @@ struct k_mem_pool {
|
||||||
extern int k_mem_pool_alloc(struct k_mem_pool *pool, struct k_mem_block *block,
|
extern int k_mem_pool_alloc(struct k_mem_pool *pool, struct k_mem_block *block,
|
||||||
size_t size, s32_t timeout);
|
size_t size, s32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate memory from a memory pool with malloc() semantics
|
||||||
|
*
|
||||||
|
* Such memory must be released using k_free().
|
||||||
|
*
|
||||||
|
* @param pool Address of the memory pool.
|
||||||
|
* @param size Amount of memory to allocate (in bytes).
|
||||||
|
* @return Address of the allocated memory if successful, otherwise NULL
|
||||||
|
*/
|
||||||
|
extern void *k_mem_pool_malloc(struct k_mem_pool *pool, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Free memory allocated from a memory pool.
|
* @brief Free memory allocated from a memory pool.
|
||||||
*
|
*
|
||||||
|
@ -3702,7 +3713,8 @@ extern void *k_malloc(size_t size);
|
||||||
* @brief Free memory allocated from heap.
|
* @brief Free memory allocated from heap.
|
||||||
*
|
*
|
||||||
* This routine provides traditional free() semantics. The memory being
|
* This routine provides traditional free() semantics. The memory being
|
||||||
* returned must have been allocated from the heap memory pool.
|
* returned must have been allocated from the heap memory pool or
|
||||||
|
* k_mem_pool_malloc().
|
||||||
*
|
*
|
||||||
* If @a ptr is NULL, no operation is performed.
|
* If @a ptr is NULL, no operation is performed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -119,6 +119,40 @@ void k_mem_pool_free(struct k_mem_block *block)
|
||||||
k_mem_pool_free_id(&block->id);
|
k_mem_pool_free_id(&block->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *k_mem_pool_malloc(struct k_mem_pool *pool, size_t size)
|
||||||
|
{
|
||||||
|
struct k_mem_block block;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get a block large enough to hold an initial (hidden) block
|
||||||
|
* descriptor, as well as the space the caller requested
|
||||||
|
*/
|
||||||
|
if (__builtin_add_overflow(size, sizeof(struct k_mem_block_id),
|
||||||
|
&size)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (k_mem_pool_alloc(pool, &block, size, K_NO_WAIT) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save the block descriptor info at the start of the actual block */
|
||||||
|
memcpy(block.data, &block.id, sizeof(struct k_mem_block_id));
|
||||||
|
|
||||||
|
/* return address of the user area part of the block to the caller */
|
||||||
|
return (char *)block.data + sizeof(struct k_mem_block_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void k_free(void *ptr)
|
||||||
|
{
|
||||||
|
if (ptr != NULL) {
|
||||||
|
/* point to hidden block descriptor at start of block */
|
||||||
|
ptr = (char *)ptr - sizeof(struct k_mem_block_id);
|
||||||
|
|
||||||
|
/* return block to the heap memory pool */
|
||||||
|
k_mem_pool_free_id(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
|
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -133,37 +167,7 @@ K_MEM_POOL_DEFINE(_heap_mem_pool, 64, CONFIG_HEAP_MEM_POOL_SIZE, 1, 4);
|
||||||
|
|
||||||
void *k_malloc(size_t size)
|
void *k_malloc(size_t size)
|
||||||
{
|
{
|
||||||
struct k_mem_block block;
|
return k_mem_pool_malloc(_HEAP_MEM_POOL, size);
|
||||||
|
|
||||||
/*
|
|
||||||
* get a block large enough to hold an initial (hidden) block
|
|
||||||
* descriptor, as well as the space the caller requested
|
|
||||||
*/
|
|
||||||
if (__builtin_add_overflow(size, sizeof(struct k_mem_block_id),
|
|
||||||
&size)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (k_mem_pool_alloc(_HEAP_MEM_POOL, &block, size, K_NO_WAIT) != 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* save the block descriptor info at the start of the actual block */
|
|
||||||
memcpy(block.data, &block.id, sizeof(struct k_mem_block_id));
|
|
||||||
|
|
||||||
/* return address of the user area part of the block to the caller */
|
|
||||||
return (char *)block.data + sizeof(struct k_mem_block_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void k_free(void *ptr)
|
|
||||||
{
|
|
||||||
if (ptr != NULL) {
|
|
||||||
/* point to hidden block descriptor at start of block */
|
|
||||||
ptr = (char *)ptr - sizeof(struct k_mem_block_id);
|
|
||||||
|
|
||||||
/* return block to the heap memory pool */
|
|
||||||
k_mem_pool_free_id(ptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *k_calloc(size_t nmemb, size_t size)
|
void *k_calloc(size_t nmemb, size_t size)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue