mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
heap: pushed down all the aligned_alloc / free implementation
This commit is contained in:
parent
15cdd2859a
commit
5ce7ec848c
@ -472,20 +472,20 @@ void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size)
|
||||
|
||||
void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_t alignment)
|
||||
{
|
||||
if(heap == NULL) {
|
||||
if (heap == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!size) {
|
||||
if (!size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!alignment) {
|
||||
if (!alignment) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Alignment must be a power of two...
|
||||
if((alignment & (alignment - 1)) != 0) {
|
||||
if ((alignment & (alignment - 1)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -493,7 +493,7 @@ void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_
|
||||
|
||||
multi_heap_internal_lock(heap);
|
||||
void *head = multi_heap_malloc_impl(heap, size + overhead);
|
||||
if(head == NULL) {
|
||||
if (head == NULL) {
|
||||
multi_heap_internal_unlock(heap);
|
||||
return NULL;
|
||||
}
|
||||
@ -510,13 +510,18 @@ void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_
|
||||
|
||||
void multi_heap_aligned_free_impl(multi_heap_handle_t heap, void *p)
|
||||
{
|
||||
if(p == NULL) {
|
||||
if (p == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
multi_heap_internal_lock(heap);
|
||||
uint32_t offset = *((uint32_t *)p - 1);
|
||||
void *block_head = (void *)((uint8_t *)p - offset);
|
||||
|
||||
#ifdef MULTI_HEAP_POISONING_SLOW
|
||||
multi_heap_internal_poison_fill_region(block_head, multi_heap_get_allocated_size_impl(heap, block_head), true /* free */);
|
||||
#endif
|
||||
|
||||
multi_heap_free_impl(heap, block_head);
|
||||
multi_heap_internal_unlock(heap);
|
||||
}
|
||||
|
@ -25,7 +25,9 @@ typedef const struct heap_block *multi_heap_block_handle_t;
|
||||
*/
|
||||
|
||||
void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size);
|
||||
void *multi_heap_aligned_alloc_impl(multi_heap_handle_t heap, size_t size, size_t alignment);
|
||||
void multi_heap_free_impl(multi_heap_handle_t heap, void *p);
|
||||
void multi_heap_aligned_free_impl(multi_heap_handle_t heap, void *p);
|
||||
void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size);
|
||||
multi_heap_handle_t multi_heap_register_impl(void *start, size_t size);
|
||||
void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info);
|
||||
|
@ -187,55 +187,28 @@ static bool verify_fill_pattern(void *data, size_t size, bool print_errors, bool
|
||||
|
||||
void *multi_heap_aligned_alloc(multi_heap_handle_t heap, size_t size, size_t alignment)
|
||||
{
|
||||
if(heap == NULL) {
|
||||
if (size > SIZE_MAX - POISON_OVERHEAD) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!alignment) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Alignment must be a power of two...
|
||||
if((alignment & (alignment - 1)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(size > SIZE_MAX - POISON_OVERHEAD) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t overhead = (sizeof(uint32_t) + (alignment - 1) + POISON_OVERHEAD);
|
||||
|
||||
multi_heap_internal_lock(heap);
|
||||
poison_head_t *head = multi_heap_malloc_impl(heap, size + overhead);
|
||||
poison_head_t *head = multi_heap_aligned_alloc_impl(heap, size + POISON_OVERHEAD, alignment);
|
||||
uint8_t *data = NULL;
|
||||
if (head != NULL) {
|
||||
data = poison_allocated_region(head, size + (overhead - POISON_OVERHEAD));
|
||||
data = poison_allocated_region(head, size);
|
||||
#ifdef SLOW
|
||||
/* check everything we got back is FREE_FILL_PATTERN & swap for MALLOC_FILL_PATTERN */
|
||||
bool ret = verify_fill_pattern(data, size, true, true, true);
|
||||
assert( ret );
|
||||
#else
|
||||
(void)data;
|
||||
#endif
|
||||
} else {
|
||||
multi_heap_internal_unlock(heap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Lets align our new obtained block address:
|
||||
//and save information to recover original block pointer
|
||||
//to allow us to deallocate the memory when needed
|
||||
void *ptr = (void *)ALIGN_UP((uintptr_t)head + sizeof(uint32_t) + sizeof(poison_head_t), alignment);
|
||||
*((uint32_t *)ptr - 1) = (uint32_t)((uintptr_t)ptr - (uintptr_t)head);
|
||||
|
||||
multi_heap_internal_unlock(heap);
|
||||
|
||||
return ptr;
|
||||
return data;
|
||||
}
|
||||
|
||||
void *multi_heap_malloc(multi_heap_handle_t heap, size_t size)
|
||||
@ -261,25 +234,16 @@ void *multi_heap_malloc(multi_heap_handle_t heap, size_t size)
|
||||
|
||||
void multi_heap_aligned_free(multi_heap_handle_t heap, void *p)
|
||||
{
|
||||
if(p == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
multi_heap_internal_lock(heap);
|
||||
|
||||
uint32_t offset = *((uint32_t *)p - 1);
|
||||
void *block_head = (void *)((uint8_t *)p - offset);
|
||||
block_head += sizeof(poison_head_t);
|
||||
|
||||
poison_head_t *head = verify_allocated_region(block_head, true);
|
||||
poison_head_t *head = verify_allocated_region(p, true);
|
||||
assert(head != NULL);
|
||||
block_head -= sizeof(poison_head_t);
|
||||
|
||||
#ifdef SLOW
|
||||
/* replace everything with FREE_FILL_PATTERN, including the poison head/tail */
|
||||
memset(block_head, FREE_FILL_PATTERN, head->alloc_size + POISON_OVERHEAD);
|
||||
memset(head, FREE_FILL_PATTERN, head->alloc_size + POISON_OVERHEAD);
|
||||
#endif
|
||||
|
||||
multi_heap_free_impl(heap, block_head);
|
||||
multi_heap_aligned_free_impl(heap, head);
|
||||
multi_heap_internal_unlock(heap);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,14 @@ TEST_CASE("Capabilities aligned allocator test", "[heap]")
|
||||
printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments);
|
||||
printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf);
|
||||
//Address of obtained block must be aligned with selected value
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
|
||||
if((alignments & 0x03) == 0) {
|
||||
//Alignment is a multiple of four:
|
||||
TEST_ASSERT(((intptr_t)buf & 0x03) == 0);
|
||||
} else {
|
||||
//Exotic alignments:
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
}
|
||||
|
||||
//Write some data, if it corrupts memory probably the heap
|
||||
//canary verification will fail:
|
||||
@ -57,8 +64,13 @@ TEST_CASE("Capabilities aligned allocator test", "[heap]")
|
||||
printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments);
|
||||
printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf);
|
||||
//Address of obtained block must be aligned with selected value
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
|
||||
if((alignments & 0x03) == 0) {
|
||||
//Alignment is a multiple of four:
|
||||
TEST_ASSERT(((intptr_t)buf & 0x03) == 0);
|
||||
} else {
|
||||
//Exotic alignments:
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
}
|
||||
//Write some data, if it corrupts memory probably the heap
|
||||
//canary verification will fail:
|
||||
memset(buf, 0xA5, (10*1024));
|
||||
@ -85,7 +97,13 @@ TEST_CASE("Capabilities aligned calloc test", "[heap]")
|
||||
printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments);
|
||||
printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf);
|
||||
//Address of obtained block must be aligned with selected value
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
if((alignments & 0x03) == 0) {
|
||||
//Alignment is a multiple of four:
|
||||
TEST_ASSERT(((intptr_t)buf & 0x03) == 0);
|
||||
} else {
|
||||
//Exotic alignments:
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
}
|
||||
|
||||
//Write some data, if it corrupts memory probably the heap
|
||||
//canary verification will fail:
|
||||
@ -126,8 +144,13 @@ TEST_CASE("Capabilities aligned calloc test", "[heap]")
|
||||
printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments);
|
||||
printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf);
|
||||
//Address of obtained block must be aligned with selected value
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
|
||||
if((alignments & 0x03) == 0) {
|
||||
//Alignment is a multiple of four:
|
||||
TEST_ASSERT(((intptr_t)buf & 0x03) == 0);
|
||||
} else {
|
||||
//Exotic alignments:
|
||||
TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0);
|
||||
}
|
||||
//Write some data, if it corrupts memory probably the heap
|
||||
//canary verification will fail:
|
||||
memset(buf, 0xA5, (10*1024));
|
||||
|
@ -495,8 +495,6 @@ TEST_CASE("unaligned heaps", "[multi_heap]")
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_HEAP_POISONING_NONE
|
||||
|
||||
TEST_CASE("multi_heap aligned allocations", "[multi_heap]")
|
||||
{
|
||||
uint8_t test_heap[1024 * 1024];
|
||||
@ -527,7 +525,14 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]")
|
||||
//printf("[ALIGNED_ALLOC] allocated size: %d \n", multi_heap_get_allocated_size(heap, buf));
|
||||
printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf);
|
||||
//Address of obtained block must be aligned with selected value
|
||||
REQUIRE(((intptr_t)buf & (aligments - 1)) == 0);
|
||||
|
||||
if((aligments & 0x03) == 0) {
|
||||
//Alignment is a multiple of four:
|
||||
REQUIRE(((intptr_t)buf & 0x03) == 0);
|
||||
} else {
|
||||
//Exotic alignments:
|
||||
REQUIRE(((intptr_t)buf & (aligments - 1)) == 0);
|
||||
}
|
||||
|
||||
//Write some data, if it corrupts memory probably the heap
|
||||
//canary verification will fail:
|
||||
@ -539,6 +544,4 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]")
|
||||
|
||||
printf("[ALIGNED_ALLOC] heap_size after: %d \n", multi_heap_free_size(heap));
|
||||
REQUIRE((old_size - multi_heap_free_size(heap)) <= leakage);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue
Block a user