malloc: make sure returned memory is properly aligned
The accounting data stored at the beginning of a memory block used by malloc must push the returned memory address to a word boundary. This is already the case on 32-bit systems, but not on 64-bit systems where e.g. struct k_mem_block_id still has a size of 4. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
1578ef71b1
commit
39cd2ebef7
3 changed files with 10 additions and 8 deletions
|
@ -141,7 +141,8 @@ void *k_mem_pool_malloc(struct k_mem_pool *pool, size_t size)
|
|||
* get a block large enough to hold an initial (hidden) block
|
||||
* descriptor, as well as the space the caller requested
|
||||
*/
|
||||
if (size_add_overflow(size, sizeof(struct k_mem_block_id), &size)) {
|
||||
if (size_add_overflow(size, WB_UP(sizeof(struct k_mem_block_id)),
|
||||
&size)) {
|
||||
return NULL;
|
||||
}
|
||||
if (k_mem_pool_alloc(pool, &block, size, K_NO_WAIT) != 0) {
|
||||
|
@ -152,14 +153,14 @@ void *k_mem_pool_malloc(struct k_mem_pool *pool, size_t size)
|
|||
(void)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);
|
||||
return (char *)block.data + WB_UP(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);
|
||||
ptr = (char *)ptr - WB_UP(sizeof(struct k_mem_block_id));
|
||||
|
||||
/* return block to the heap memory pool */
|
||||
k_mem_pool_free_id(ptr);
|
||||
|
|
|
@ -349,7 +349,7 @@ void *sys_mem_pool_alloc(struct sys_mem_pool *p, size_t size)
|
|||
|
||||
sys_mutex_lock(&p->mutex, K_FOREVER);
|
||||
|
||||
size += sizeof(struct sys_mem_pool_block);
|
||||
size += WB_UP(sizeof(struct sys_mem_pool_block));
|
||||
if (z_sys_mem_pool_block_alloc(&p->base, size, &level, &block,
|
||||
(void **)&ret)) {
|
||||
ret = NULL;
|
||||
|
@ -360,7 +360,7 @@ void *sys_mem_pool_alloc(struct sys_mem_pool *p, size_t size)
|
|||
blk->level = level;
|
||||
blk->block = block;
|
||||
blk->pool = p;
|
||||
ret += sizeof(*blk);
|
||||
ret += WB_UP(sizeof(struct sys_mem_pool_block));
|
||||
out:
|
||||
sys_mutex_unlock(&p->mutex);
|
||||
return ret;
|
||||
|
@ -375,7 +375,8 @@ void sys_mem_pool_free(void *ptr)
|
|||
return;
|
||||
}
|
||||
|
||||
blk = (struct sys_mem_pool_block *)((char *)ptr - sizeof(*blk));
|
||||
ptr = (char *)ptr - WB_UP(sizeof(struct sys_mem_pool_block));
|
||||
blk = (struct sys_mem_pool_block *)ptr;
|
||||
p = blk->pool;
|
||||
|
||||
sys_mutex_lock(&p->mutex, K_FOREVER);
|
||||
|
|
|
@ -31,12 +31,12 @@ void test_mheap_malloc_align4(void)
|
|||
|
||||
/**
|
||||
* TESTPOINT: The address of the allocated chunk is guaranteed to be
|
||||
* aligned on a multiple of 4 bytes.
|
||||
* aligned on a word boundary (4 or 8 bytes).
|
||||
*/
|
||||
for (int i = 0; i < BLK_NUM_MAX; i++) {
|
||||
block[i] = k_malloc(i);
|
||||
zassert_not_null(block[i], NULL);
|
||||
zassert_false((int)block[i] % 4, NULL);
|
||||
zassert_false((uintptr_t)block[i] % sizeof(void *), NULL);
|
||||
}
|
||||
|
||||
/* test case tear down*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue