Heap: heap_caps_*_prefer functions now properly call alloc_failed callback

heap_caps_*_prefer functions will now only call heaps_caps_alloc_failed
callback if all attempts to allocation memory fail (and not after each attempt
anymore).

* Closes https://github.com/espressif/esp-idf/issues/9086
This commit is contained in:
Omar Chebib
2022-06-08 14:33:11 +08:00
parent 56a89b920d
commit 05575cc246

View File

@@ -24,8 +24,11 @@
#include "esp_system.h" #include "esp_system.h"
// forward declaration /* Forward declaration for base function, put in IRAM.
IRAM_ATTR static void *heap_caps_realloc_base( void *ptr, size_t size, uint32_t caps); * These functions don't check for errors after trying to allocate memory. */
static void *heap_caps_realloc_base( void *ptr, size_t size, uint32_t caps );
static void *heap_caps_calloc_base( size_t n, size_t size, uint32_t caps );
static void *heap_caps_malloc_base( size_t size, uint32_t caps );
/* /*
This file, combined with a region allocator that supports multiple heaps, solves the problem that the ESP32 has RAM This file, combined with a region allocator that supports multiple heaps, solves the problem that the ESP32 has RAM
@@ -256,13 +259,17 @@ IRAM_ATTR void *heap_caps_malloc_prefer( size_t size, size_t num, ... )
va_list argp; va_list argp;
va_start( argp, num ); va_start( argp, num );
void *r = NULL; void *r = NULL;
uint32_t caps = MALLOC_CAP_DEFAULT;
while (num--) { while (num--) {
uint32_t caps = va_arg( argp, uint32_t ); caps = va_arg( argp, uint32_t );
r = heap_caps_malloc( size, caps ); r = heap_caps_malloc_base( size, caps );
if (r != NULL) { if (r != NULL) {
break; break;
} }
} }
if (r == NULL){
heap_caps_alloc_failed(size, caps, __func__);
}
va_end( argp ); va_end( argp );
return r; return r;
} }
@@ -275,13 +282,17 @@ IRAM_ATTR void *heap_caps_realloc_prefer( void *ptr, size_t size, size_t num, ..
va_list argp; va_list argp;
va_start( argp, num ); va_start( argp, num );
void *r = NULL; void *r = NULL;
uint32_t caps = MALLOC_CAP_DEFAULT;
while (num--) { while (num--) {
uint32_t caps = va_arg( argp, uint32_t ); caps = va_arg( argp, uint32_t );
r = heap_caps_realloc( ptr, size, caps ); r = heap_caps_realloc_base( ptr, size, caps );
if (r != NULL || size == 0) { if (r != NULL || size == 0) {
break; break;
} }
} }
if (r == NULL){
heap_caps_alloc_failed(size, caps, __func__);
}
va_end( argp ); va_end( argp );
return r; return r;
} }
@@ -294,10 +305,16 @@ IRAM_ATTR void *heap_caps_calloc_prefer( size_t n, size_t size, size_t num, ...
va_list argp; va_list argp;
va_start( argp, num ); va_start( argp, num );
void *r = NULL; void *r = NULL;
uint32_t caps = MALLOC_CAP_DEFAULT;
while (num--) { while (num--) {
uint32_t caps = va_arg( argp, uint32_t ); caps = va_arg( argp, uint32_t );
r = heap_caps_calloc( n, size, caps ); r = heap_caps_calloc_base( n, size, caps );
if (r != NULL) break; if (r != NULL){
break;
}
}
if (r == NULL){
heap_caps_alloc_failed(size, caps, __func__);
} }
va_end( argp ); va_end( argp );
return r; return r;
@@ -429,7 +446,11 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, uint32_t caps)
return ptr; return ptr;
} }
IRAM_ATTR void *heap_caps_calloc( size_t n, size_t size, uint32_t caps) /*
This function should not be called directly as it does not
check for failure / call heap_caps_alloc_failed()
*/
IRAM_ATTR static void *heap_caps_calloc_base( size_t n, size_t size, uint32_t caps)
{ {
void *result; void *result;
size_t size_bytes; size_t size_bytes;
@@ -438,13 +459,24 @@ IRAM_ATTR void *heap_caps_calloc( size_t n, size_t size, uint32_t caps)
return NULL; return NULL;
} }
result = heap_caps_malloc(size_bytes, caps); result = heap_caps_malloc_base(size_bytes, caps);
if (result != NULL) { if (result != NULL) {
bzero(result, size_bytes); bzero(result, size_bytes);
} }
return result; return result;
} }
IRAM_ATTR void *heap_caps_calloc( size_t n, size_t size, uint32_t caps)
{
void* ptr = heap_caps_calloc_base(n, size, caps);
if (!ptr){
heap_caps_alloc_failed(size, caps, __func__);
}
return ptr;
}
size_t heap_caps_get_total_size(uint32_t caps) size_t heap_caps_get_total_size(uint32_t caps)
{ {
size_t total_size = 0; size_t total_size = 0;