From 9dcd76a6502d694ff48d8797230973c2feb6750c Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 23 Oct 2020 17:45:46 -0400 Subject: [PATCH] lib/os/heap: minimize initial overallocation in the aligned case The biggest required padding is equal to `align - chunk_header_bytes` and not `align - 1` given that the header already contributes to the padding. Signed-off-by: Nicolas Pitre --- lib/os/heap.c | 3 ++- tests/lib/heap_align/src/main.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/os/heap.c b/lib/os/heap.c index 9f4b35ff258..5bc509a2e20 100644 --- a/lib/os/heap.c +++ b/lib/os/heap.c @@ -261,7 +261,8 @@ void *sys_heap_aligned_alloc(struct sys_heap *heap, size_t align, size_t bytes) * We over-allocate to account for alignment and then free * the extra allocations afterwards. */ - size_t padded_sz = bytes_to_chunksz(h, bytes + align - 1); + size_t padded_sz = + bytes_to_chunksz(h, bytes + align - chunk_header_bytes(h)); chunkid_t c0 = alloc_chunk(h, padded_sz); if (c0 == 0) { diff --git a/tests/lib/heap_align/src/main.c b/tests/lib/heap_align/src/main.c index fda89b8e594..678ba2e1fcc 100644 --- a/tests/lib/heap_align/src/main.c +++ b/tests/lib/heap_align/src/main.c @@ -60,7 +60,7 @@ static void check_heap_align(struct sys_heap *h, static void test_aligned_alloc(void) { struct sys_heap heap = {}; - void *p; + void *p, *q; sys_heap_init(&heap, heapmem, HEAP_SZ); @@ -87,6 +87,15 @@ static void test_aligned_alloc(void) memset(p, 0, 12); zassert_true(sys_heap_validate(&heap), "heap invalid"); sys_heap_free(&heap, p); + + /* corner case with minimizing the overallocation before alignment */ + p = sys_heap_aligned_alloc(&heap, 16, 16); + q = sys_heap_aligned_alloc(&heap, 16, 17); + memset(p, 0, 16); + memset(q, 0, 17); + zassert_true(sys_heap_validate(&heap), "heap invalid"); + sys_heap_free(&heap, p); + sys_heap_free(&heap, q); } void test_main(void)