lib/mem_blocks: add allocation for contiguous memory blocks

Added allocation and freeing of a contiguous memory blocks

Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
This commit is contained in:
Marcin Szkudlinski 2022-03-15 13:29:10 +01:00 committed by Anas Nashif
parent 297321a9e1
commit 033dbae787
2 changed files with 108 additions and 0 deletions

View file

@ -218,6 +218,22 @@ struct sys_multi_mem_blocks {
int sys_mem_blocks_alloc(sys_mem_blocks_t *mem_block, size_t count,
void **out_blocks);
/**
* @brief Allocate a contiguous set of memory blocks
*
* Allocate multiple memory blocks, and place their pointers into
* the output array.
*
* @param[in] mem_block Pointer to memory block object.
* @param[in] count Number of blocks to allocate.
* @param[out] out_block Output pointer to the start of the allocated block set
*
* @retval 0 Successful
* @retval -EINVAL Invalid argument supplied.
* @retval -ENOMEM Not enough contiguous blocks for allocation.
*/
int sys_mem_blocks_alloc_contiguous(sys_mem_blocks_t *mem_block, size_t count,
void **out_block);
/**
* @brief Force allocation of a specified blocks in a memory block object
@ -254,6 +270,21 @@ int sys_mem_blocks_get(sys_mem_blocks_t *mem_block, void *in_block, size_t count
int sys_mem_blocks_free(sys_mem_blocks_t *mem_block, size_t count,
void **in_blocks);
/**
* @brief Free contiguous multiple memory blocks
*
* Free contiguous multiple memory blocks
*
* @param[in] mem_block Pointer to memory block object.
* @param[in] block Pointer to the first memory block
* @param[in] count Number of blocks to free.
*
* @retval 0 Successful
* @retval -EINVAL Invalid argument supplied.
* @retval -EFAULT Invalid pointer supplied.
*/
int sys_mem_blocks_free_contiguous(sys_mem_blocks_t *mem_block, void *block, size_t count);
/**
* @brief Initialize multi memory blocks allocator group
*

View file

@ -57,6 +57,45 @@ out:
return ret;
}
int sys_mem_blocks_alloc_contiguous(sys_mem_blocks_t *mem_block, size_t count,
void **out_block)
{
int ret = 0;
if ((mem_block == NULL) || (out_block == NULL)) {
ret = -EINVAL;
goto out;
}
if (count == 0) {
/* Nothing to allocate */
*out_block = NULL;
goto out;
}
if (count > mem_block->num_blocks) {
/* Definitely not enough blocks to be allocated */
ret = -ENOMEM;
goto out;
}
void *ptr = alloc_blocks(mem_block, count);
if (ptr == NULL) {
ret = -ENOMEM;
goto out;
}
*out_block = ptr;
#ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
heap_listener_notify_alloc(HEAP_ID_FROM_POINTER(mem_block),
ptr, count << mem_block->blk_sz_shift);
#endif
out:
return ret;
}
int sys_mem_blocks_alloc(sys_mem_blocks_t *mem_block, size_t count,
void **out_blocks)
{
@ -204,6 +243,44 @@ out:
return ret;
}
int sys_mem_blocks_free_contiguous(sys_mem_blocks_t *mem_block, void *block, size_t count)
{
int ret = 0;
if (mem_block == NULL) {
ret = -EINVAL;
goto out;
}
CHECKIF((mem_block->bitmap == NULL) || (mem_block->buffer == NULL)) {
ret = -EINVAL;
goto out;
}
if (count == 0) {
/* Nothing to be freed. */
goto out;
}
if (count > mem_block->num_blocks) {
ret = -EINVAL;
goto out;
}
ret = free_blocks(mem_block, block, count);
if (ret != 0) {
goto out;
}
#ifdef CONFIG_SYS_MEM_BLOCKS_LISTENER
heap_listener_notify_free(HEAP_ID_FROM_POINTER(mem_block),
block, count << mem_block->blk_sz_shift);
#endif
out:
return ret;
}
void sys_multi_mem_blocks_init(sys_multi_mem_blocks_t *group,
sys_multi_mem_blocks_choice_fn_t choice_fn)
{