From 75e1c4d0fbbf409dc220e4008e1713b7ddb038fe Mon Sep 17 00:00:00 2001 From: Guillaume Souchere Date: Thu, 13 Oct 2022 10:05:53 +0200 Subject: [PATCH] heap: Update host tests after incorporation of the new TLSF implementation --- .../test_multi_heap_host/test_multi_heap.cpp | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/components/heap/test_multi_heap_host/test_multi_heap.cpp b/components/heap/test_multi_heap_host/test_multi_heap.cpp index 90bb44589e..d376e106bb 100644 --- a/components/heap/test_multi_heap_host/test_multi_heap.cpp +++ b/components/heap/test_multi_heap_host/test_multi_heap.cpp @@ -8,6 +8,14 @@ #include #include + +/* The functions __malloc__ and __free__ are used to call the libc + * malloc and free and allocate memory from the host heap. Since the test + * `TEST_CASE("multi_heap many random allocations", "[multi_heap]")` + * calls multi_heap_allocation_impl() with sizes that can go up to 8MB, + * an allocatation on the heap will be prefered rather than the stack which + * might not have the necessary memory. + */ static void *__malloc__(size_t bytes) { return malloc(bytes); @@ -71,10 +79,11 @@ TEST_CASE("multi_heap simple allocations", "[multi_heap]") TEST_CASE("multi_heap fragmentation", "[multi_heap]") { - uint8_t small_heap[4 * 1024]; + const size_t HEAP_SIZE = 4 * 1024; + uint8_t small_heap[HEAP_SIZE]; multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap)); - const size_t alloc_size = 128; + const size_t alloc_size = 500; void *p[4]; for (int i = 0; i < 4; i++) { @@ -216,7 +225,7 @@ TEST_CASE("multi_heap defrag realloc", "[multi_heap]") void multi_heap_allocation_impl(int heap_size) { - uint8_t *big_heap = (uint8_t *) __malloc__(2*heap_size); + uint8_t *big_heap = (uint8_t *) __malloc__(heap_size); const int NUM_POINTERS = 64; printf("Running multi-allocation test with heap_size %d...\n", heap_size); @@ -229,7 +238,7 @@ void multi_heap_allocation_impl(int heap_size) const size_t initial_free = multi_heap_free_size(heap); - const int ITERATIONS = 10000; + const int ITERATIONS = 5000; for (int i = 0; i < ITERATIONS; i++) { /* check all pointers allocated so far are valid inside big_heap */ @@ -240,11 +249,11 @@ void multi_heap_allocation_impl(int heap_size) uint8_t n = rand() % NUM_POINTERS; - if (rand() % 4 == 0) { + if (i % 4 == 0) { /* 1 in 4 iterations, try to realloc the buffer instead of using malloc/free */ - size_t new_size = rand() % 1024; + size_t new_size = (rand() % 1023) + 1; void *new_p = multi_heap_realloc(heap, p[n], new_size); printf("realloc %p -> %p (%zu -> %zu)\n", p[n], new_p, s[n], new_size); multi_heap_check(heap, true); @@ -412,8 +421,9 @@ TEST_CASE("multi_heap minimum-size allocations", "[multi_heap]") TEST_CASE("multi_heap_realloc()", "[multi_heap]") { + const size_t HEAP_SIZE = 4 * 1024; const uint32_t PATTERN = 0xABABDADA; - uint8_t small_heap[4 * 1024]; + uint8_t small_heap[HEAP_SIZE]; multi_heap_handle_t heap = multi_heap_register(small_heap, sizeof(small_heap)); uint32_t *a = (uint32_t *)multi_heap_malloc(heap, 64); @@ -423,7 +433,6 @@ TEST_CASE("multi_heap_realloc()", "[multi_heap]") REQUIRE( b > a); /* 'b' takes the block after 'a' */ *a = PATTERN; - uint32_t *c = (uint32_t *)multi_heap_realloc(heap, a, 72); REQUIRE( multi_heap_check(heap, true)); REQUIRE( c != NULL ); @@ -433,13 +442,12 @@ TEST_CASE("multi_heap_realloc()", "[multi_heap]") #ifndef MULTI_HEAP_POISONING_SLOW // "Slow" poisoning implementation doesn't reallocate in place, so these // test will fail... - uint32_t *d = (uint32_t *)multi_heap_realloc(heap, c, 36); REQUIRE( multi_heap_check(heap, true) ); REQUIRE( c == d ); /* 'c' block should be shrunk in-place */ REQUIRE( *d == PATTERN); - - uint32_t *e = (uint32_t *)multi_heap_malloc(heap, 64); + // biggest allocation possible to completely fill the block left free after it was reallocated + uint32_t *e = (uint32_t *)multi_heap_malloc(heap, 60); REQUIRE( multi_heap_check(heap, true)); REQUIRE( a == e ); /* 'e' takes the block formerly occupied by 'a' */ @@ -448,11 +456,7 @@ TEST_CASE("multi_heap_realloc()", "[multi_heap]") REQUIRE( multi_heap_check(heap, true) ); REQUIRE( f == b ); /* 'b' should be extended in-place, over space formerly occupied by 'd' */ -#ifdef MULTI_HEAP_POISONING -#define TOO_MUCH 7420 + 1 -#else -#define TOO_MUCH 7420 + 1 -#endif +#define TOO_MUCH HEAP_SIZE + 1 /* not enough contiguous space left in the heap */ uint32_t *g = (uint32_t *)multi_heap_realloc(heap, e, TOO_MUCH); REQUIRE( g == NULL ); @@ -462,7 +466,8 @@ TEST_CASE("multi_heap_realloc()", "[multi_heap]") g = (uint32_t *)multi_heap_realloc(heap, e, 128); REQUIRE( multi_heap_check(heap, true) ); REQUIRE( e == g ); /* 'g' extends 'e' in place, into the space formerly held by 'f' */ -#endif + +#endif // MULTI_HEAP_POISONING_SLOW } // TLSF only accepts heaps aligned to 4-byte boundary so @@ -561,8 +566,12 @@ TEST_CASE("multi_heap poisoning detection", "[multi_heap]") /* register the heap memory. One free block only will be available */ multi_heap_handle_t heap = multi_heap_register(heap_mem, HEAP_SIZE); + control_t *tlsf_ptr = (control_t*)(heap_mem + 20); + const size_t control_t_size = tlsf_ptr->size; + const size_t heap_t_size = 20; + /* offset in memory at which to find the first free memory byte */ - const size_t free_memory_offset = sizeof(multi_heap_info_t) + sizeof(control_t) + block_header_overhead; + const size_t free_memory_offset = heap_t_size + control_t_size + sizeof(block_header_t) - block_header_overhead; /* block header of the free block under test in the heap () */ const block_header_t* block = (block_header_t*)(heap_mem + free_memory_offset - sizeof(block_header_t));