diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 9df5fb212ea..5e65ee8e038 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -655,31 +655,10 @@ size_t heap_caps_get_allocated_size( void *ptr ) return size; } -HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps) +static HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_base(size_t alignment, size_t size, uint32_t caps) { void *ret = NULL; - if(!alignment) { - return NULL; - } - - //Alignment must be a power of two: - if((alignment & (alignment - 1)) != 0) { - return NULL; - } - - if (size == 0) { - return NULL; - } - - if (size > HEAP_SIZE_MAX) { - // Avoids int overflow when adding small numbers to size, or - // calculating 'end' from start+size, by limiting 'size' to the possible range - heap_caps_alloc_failed(size, caps, __func__); - - return NULL; - } - for (int prio = 0; prio < SOC_MEMORY_TYPE_NO_PRIOS; prio++) { //Iterate over heaps and check capabilities at this priority heap_t *heap; @@ -702,12 +681,83 @@ HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint } } - heap_caps_alloc_failed(size, caps, __func__); - //Nothing usable found. return NULL; } +static HEAP_IRAM_ATTR int heap_caps_aligned_check_args(size_t alignment, size_t size, const char *funcname) { + if (!alignment) { + return -1; + } + + // Alignment must be a power of two: + if ((alignment & (alignment - 1)) != 0) { + return -1; + } + + if (size == 0) { + return -1; + } + + if (size > HEAP_SIZE_MAX) { + // Avoids int overflow when adding small numbers to size, or + // calculating 'end' from start+size, by limiting 'size' to the possible range + heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, funcname); + + return -1; + } + + return 0; +} + +HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_default(size_t alignment, size_t size) +{ + void *ret = NULL; + + if (malloc_alwaysinternal_limit == MALLOC_DISABLE_EXTERNAL_ALLOCS) { + return heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + } + + if (heap_caps_aligned_check_args(alignment, size, __func__) != 0) { + return NULL; + } + + if (size <= (size_t)malloc_alwaysinternal_limit) { + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + } else { + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM); + } + + if (ret != NULL) { + return ret; + } + + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT); + + if (ret == NULL) { + heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, __func__); + } + + return ret; +} + +HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps) +{ + void *ret = NULL; + + if (heap_caps_aligned_check_args(alignment, size, __func__) != 0) { + return NULL; + } + + ret = heap_caps_aligned_alloc_base(alignment, size, caps); + + if (ret == NULL) { + heap_caps_alloc_failed(size, caps, __func__); + } + + return ret; +} + HEAP_IRAM_ATTR void heap_caps_aligned_free(void *ptr) { heap_caps_free(ptr); diff --git a/components/heap/heap_private.h b/components/heap/heap_private.h index 51b6773ffad..fde7a78bcfd 100644 --- a/components/heap/heap_private.h +++ b/components/heap/heap_private.h @@ -62,6 +62,7 @@ inline static uint32_t get_all_caps(const heap_t *heap) */ void *heap_caps_realloc_default(void *p, size_t size); void *heap_caps_malloc_default(size_t size); +void *heap_caps_aligned_alloc_default(size_t alignment, size_t size); #ifdef __cplusplus diff --git a/components/newlib/heap.c b/components/newlib/heap.c index fca44906a2d..685e1e3c721 100644 --- a/components/newlib/heap.c +++ b/components/newlib/heap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ */ extern void *heap_caps_malloc_default( size_t size ); extern void *heap_caps_realloc_default( void *ptr, size_t size ); +extern void *heap_caps_aligned_alloc_default( size_t alignment, size_t size ); void* malloc(size_t size) { @@ -71,7 +72,7 @@ void* _calloc_r(struct _reent *r, size_t nmemb, size_t size) void* memalign(size_t alignment, size_t n) { - return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT); + return heap_caps_aligned_alloc_default(alignment, n); } int posix_memalign(void **out_ptr, size_t alignment, size_t size) @@ -81,7 +82,7 @@ int posix_memalign(void **out_ptr, size_t alignment, size_t size) *out_ptr = NULL; return 0; } - void *result = heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT); + void *result = heap_caps_aligned_alloc_default(alignment, size); if (result != NULL) { /* Modify output pointer only on success */ *out_ptr = result; diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 2167932fe25..320d66e77e8 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -22,9 +22,7 @@ components/esp_rom/include/esp32s2/rom/rsa_pss.h # LWIP: sockets.h uses #include_next<>, which doesn't work correctly with the checker # memp_std.h is supposed to be included multiple times with different settings -components/lwip/lwip/src/include/lwip/priv/memp_std.h components/lwip/include/lwip/sockets.h -components/lwip/lwip/src/include/lwip/prot/nd6.h ## Header produced non-zero object: components/esp_phy/esp32/include/phy_init_data.h @@ -68,13 +66,9 @@ components/json/cJSON/ components/spiffs/include/spiffs_config.h -components/unity/unity/src/unity_internals.h -components/unity/unity/extras/ components/unity/include/unity_config.h components/unity/include/unity_test_runner.h -components/cmock/CMock/src/cmock.h -components/cmock/CMock/src/cmock_internals.h components/openthread/openthread/