kernel/k_malloc: Decouple k_malloc/k_free from mem_pool

These were implemented in terms of the mem_pool/block API directly
(for complicated reasons, the pointers returned from this API may have
been allocated from allocators other than the single system heap).
Have them use a k_heap instead.

Requires a tweak to one test which had hard-coded an assumption about
the header size.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2020-10-01 09:43:04 -07:00 committed by Anas Nashif
commit 9413922625
3 changed files with 24 additions and 21 deletions

View file

@ -13,37 +13,42 @@ void z_mem_pool_free(struct k_mem_block *block)
z_mem_pool_free_id(&block->id);
}
void *z_mem_pool_malloc(struct k_mem_pool *pool, size_t size)
void *z_heap_malloc(struct k_heap *heap, 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
* get a block large enough to hold an initial (hidden) heap
* pointer, as well as the space the caller requested
*/
if (size_add_overflow(size, WB_UP(sizeof(struct k_mem_block_id)),
if (size_add_overflow(size, sizeof(struct k_heap *),
&size)) {
return NULL;
}
if (z_mem_pool_alloc(pool, &block, size, K_NO_WAIT) != 0) {
struct k_heap **blk = k_heap_alloc(heap, size, K_NO_WAIT);
if (blk == NULL) {
return NULL;
}
/* save the block descriptor info at the start of the actual block */
(void)memcpy(block.data, &block.id, sizeof(struct k_mem_block_id));
blk[0] = heap;
/* return address of the user area part of the block to the caller */
return (char *)block.data + WB_UP(sizeof(struct k_mem_block_id));
return (char *)&blk[1];
}
void *z_mem_pool_malloc(struct k_mem_pool *pool, size_t size)
{
return z_heap_malloc(pool->heap, size);
}
void k_free(void *ptr)
{
if (ptr != NULL) {
/* point to hidden block descriptor at start of block */
ptr = (char *)ptr - WB_UP(sizeof(struct k_mem_block_id));
struct k_heap **blk = &((struct k_heap **)ptr)[-1];
struct k_heap *heap = *blk;
/* return block to the heap memory pool */
z_mem_pool_free_id(ptr);
k_heap_free(heap, blk);
}
}

View file

@ -8,5 +8,5 @@
#define BLK_SIZE_MIN 64
#define BLK_NUM_MAX (CONFIG_HEAP_MEM_POOL_SIZE / BLK_SIZE_MIN)
#define BLK_NUM_MIN (CONFIG_HEAP_MEM_POOL_SIZE / (BLK_SIZE_MIN << 2))
#define BLK_SIZE_EXCLUDE_DESC (BLK_SIZE_MIN - 16)
#define BLK_SIZE_EXCLUDE_DESC (BLK_SIZE_MIN - sizeof(void *))
#define BLK_SIZE_QUARTER (CONFIG_HEAP_MEM_POOL_SIZE >> 2)

View file

@ -58,15 +58,13 @@ void test_mheap_block_desc(void)
void *block[BLK_NUM_MAX], *block_fail;
/**
* TESTPOINT: The kernel uses the first 16 bytes of any memory block
* allocated from the heap memory pool to save the block descriptor
* information it needs to later free the block. Consequently, an
* application's request for an N byte chunk of heap memory requires a
* block that is at least (N+16) bytes long.
* TESTPOINT: The kernel uses the first bytes of any memory
* block allocated from the heap memory pool to save the heap
* pointer it needs to later free the block.
* Test steps:
* initial memory heap status (F for free, U for used):
* 64F, 64F, 64F, 64F
* 1. request 4 blocks: each (64-16) bytes, indeed 64-byte allocated
* 1. request 4 blocks: each (64-N) bytes, indeed 64-byte allocated
* 2. verify no more free blocks, any further allocation failed
*/
for (int i = 0; i < BLK_NUM_MAX; i++) {