mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
heap_caps: added special case for realloc when previous area is an diram_iram ptr, this will force a malloc/copy/free
This commit is contained in:
parent
ce9f84fba9
commit
31145f38fa
@ -275,6 +275,10 @@ IRAM_ATTR void heap_caps_free( void *ptr)
|
||||
|
||||
IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps)
|
||||
{
|
||||
bool ptr_in_diram_case = false;
|
||||
heap_t *heap = NULL;
|
||||
void *dram_ptr = NULL;
|
||||
|
||||
if (ptr == NULL) {
|
||||
return heap_caps_malloc(size, caps);
|
||||
}
|
||||
@ -288,23 +292,32 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//On esp32s2 the pointer to heap may be aliased, we need to
|
||||
//The pointer to memory may be aliased, we need to
|
||||
//recover it before to manage a new allocation:
|
||||
if(esp_ptr_in_diram_iram((void *)ptr)) {
|
||||
//pointer must be already aliased, otherwise just ignore this part:
|
||||
uint32_t *dram_addr = (uint32_t *)ptr;
|
||||
ptr = (void *)dram_addr[-1];
|
||||
dram_ptr = (void *)dram_addr[-1];
|
||||
|
||||
//printf("[HEAP_CAPS_MALLOC]: obtained pointer that was aliased: %p \n", (void *)ptr);
|
||||
|
||||
heap = find_containing_heap(dram_ptr);
|
||||
assert(heap != NULL && "realloc() pointer is outside heap areas");
|
||||
|
||||
//with pointers that reside on diram space, we avoid to
|
||||
//to use realloc implementation due to address translation issues,
|
||||
//instead force a malloc/copy/free
|
||||
ptr_in_diram_case = true;
|
||||
|
||||
} else {
|
||||
heap = find_containing_heap(ptr);
|
||||
assert(heap != NULL && "realloc() pointer is outside heap areas");
|
||||
}
|
||||
|
||||
heap_t *heap = find_containing_heap(ptr);
|
||||
assert(heap != NULL && "realloc() pointer is outside heap areas");
|
||||
|
||||
// are the existing heap's capabilities compatible with the
|
||||
// requested ones?
|
||||
bool compatible_caps = (caps & get_all_caps(heap)) == caps;
|
||||
|
||||
if (compatible_caps) {
|
||||
if (compatible_caps && !ptr_in_diram_case) {
|
||||
// try to reallocate this memory within the same heap
|
||||
// (which will resize the block if it can)
|
||||
void *r = multi_heap_realloc(heap->heap, ptr, size);
|
||||
@ -317,8 +330,16 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps)
|
||||
// in a different heap with requested capabilities.
|
||||
void *new_p = heap_caps_malloc(size, caps);
|
||||
if (new_p != NULL) {
|
||||
size_t old_size = 0;
|
||||
|
||||
//If we're dealing with aliased ptr, information regarding its containing
|
||||
//heap can only be obtained with translated address.
|
||||
if(ptr_in_diram_case) {
|
||||
old_size = multi_heap_get_allocated_size(heap->heap, dram_ptr);
|
||||
} else {
|
||||
old_size = multi_heap_get_allocated_size(heap->heap, ptr);
|
||||
}
|
||||
|
||||
size_t old_size = multi_heap_get_allocated_size(heap->heap, ptr);
|
||||
assert(old_size > 0);
|
||||
memcpy(new_p, ptr, MIN(size, old_size));
|
||||
heap_caps_free(ptr);
|
||||
|
@ -21,10 +21,6 @@
|
||||
#include <sys/param.h>
|
||||
#include <multi_heap.h>
|
||||
#include "multi_heap_internal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "heap_private.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Note: Keep platform-specific parts in this header, this source
|
||||
file should depend on libc only */
|
||||
@ -272,21 +268,8 @@ void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size)
|
||||
new_head = multi_heap_malloc_impl(heap, size + POISON_OVERHEAD);
|
||||
if (new_head != NULL) {
|
||||
result = poison_allocated_region(new_head, size);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
//We may need to deal with aliased heap pointers. here too,
|
||||
//mainly because the heap canary is located before the
|
||||
//the slot reserved to preserve original DRAM address
|
||||
//so the original user data is actually p + 4 ahead :
|
||||
if(esp_ptr_in_diram_dram((void *)p)) {
|
||||
memcpy(result, p + sizeof(intptr_t), MIN(size, orig_alloc_size));
|
||||
} else {
|
||||
memcpy(result, p , MIN(size, orig_alloc_size));
|
||||
}
|
||||
#else
|
||||
memcpy(result, p, MIN(size, orig_alloc_size));
|
||||
#endif
|
||||
multi_heap_free(heap, p);
|
||||
memcpy(result, p, MIN(size, orig_alloc_size));
|
||||
multi_heap_free(heap, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user