diff --git a/doc/kernel/memory/pools.rst b/doc/kernel/memory/pools.rst index 7eb85f9716f..cdd0ff96e29 100644 --- a/doc/kernel/memory/pools.rst +++ b/doc/kernel/memory/pools.rst @@ -151,10 +151,15 @@ since that is the closest matching size supported by the memory pool. 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 ======================== -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 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` * :cpp:func:`k_mem_pool_alloc()` * :cpp:func:`k_mem_pool_free()` +* :cpp:func:`k_mem_pool_malloc()` +* :cpp:func:`k_free()` diff --git a/include/kernel.h b/include/kernel.h index 2a9e779088d..27fa8ea5da9 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -3652,6 +3652,17 @@ struct k_mem_pool { extern int k_mem_pool_alloc(struct k_mem_pool *pool, struct k_mem_block *block, 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. * @@ -3702,7 +3713,8 @@ extern void *k_malloc(size_t size); * @brief Free memory allocated from heap. * * 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. * diff --git a/kernel/mempool.c b/kernel/mempool.c index 91b7ff77108..97f7886a837 100644 --- a/kernel/mempool.c +++ b/kernel/mempool.c @@ -119,6 +119,40 @@ void k_mem_pool_free(struct k_mem_block *block) 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) /* @@ -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) { - 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(_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); - } + return k_mem_pool_malloc(_HEAP_MEM_POOL, size); } void *k_calloc(size_t nmemb, size_t size)