mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
Merge branch 'feature/memalign_internal_external_as_malloc' into 'master'
fix(heap): memalign respect malloc_alwaysinternal_limit (PR) Closes IDFGH-11209 See merge request espressif/esp-idf!26409
This commit is contained in:
@@ -660,31 +660,8 @@ size_t heap_caps_get_allocated_size( void *ptr )
|
|||||||
return MULTI_HEAP_REMOVE_BLOCK_OWNER_SIZE(size);
|
return MULTI_HEAP_REMOVE_BLOCK_OWNER_SIZE(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 (MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(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++) {
|
for (int prio = 0; prio < SOC_MEMORY_TYPE_NO_PRIOS; prio++) {
|
||||||
//Iterate over heaps and check capabilities at this priority
|
//Iterate over heaps and check capabilities at this priority
|
||||||
heap_t *heap;
|
heap_t *heap;
|
||||||
@@ -697,7 +674,7 @@ HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint
|
|||||||
//doesn't cover, see if they're available in other prios.
|
//doesn't cover, see if they're available in other prios.
|
||||||
if ((get_all_caps(heap) & caps) == caps) {
|
if ((get_all_caps(heap) & caps) == caps) {
|
||||||
//Just try to alloc, nothing special.
|
//Just try to alloc, nothing special.
|
||||||
ret = multi_heap_aligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), alignment);
|
void *ret = multi_heap_aligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), alignment);
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
MULTI_HEAP_SET_BLOCK_OWNER(ret);
|
MULTI_HEAP_SET_BLOCK_OWNER(ret);
|
||||||
ret = MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(ret);
|
ret = MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(ret);
|
||||||
@@ -709,12 +686,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.
|
//Nothing usable found.
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HEAP_IRAM_ATTR esp_err_t heap_caps_aligned_check_args(size_t alignment, size_t size, uint32_t caps, const char *funcname)
|
||||||
|
{
|
||||||
|
if (!alignment) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alignment must be a power of two:
|
||||||
|
if ((alignment & (alignment - 1)) != 0) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(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, funcname);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, MALLOC_CAP_DEFAULT, __func__) != ESP_OK) {
|
||||||
|
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, caps, __func__) != ESP_OK) {
|
||||||
|
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_IRAM_ATTR void heap_caps_aligned_free(void *ptr)
|
||||||
{
|
{
|
||||||
heap_caps_free(ptr);
|
heap_caps_free(ptr);
|
||||||
|
@@ -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_realloc_default(void *p, size_t size);
|
||||||
void *heap_caps_malloc_default(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
|
#ifdef __cplusplus
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
extern void *heap_caps_malloc_default( size_t size );
|
extern void *heap_caps_malloc_default( size_t size );
|
||||||
extern void *heap_caps_realloc_default( void *ptr, 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)
|
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)
|
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)
|
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;
|
*out_ptr = NULL;
|
||||||
return 0;
|
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) {
|
if (result != NULL) {
|
||||||
/* Modify output pointer only on success */
|
/* Modify output pointer only on success */
|
||||||
*out_ptr = result;
|
*out_ptr = result;
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("misc - posix_memalign", "[newlib_misc]")
|
TEST_CASE("misc - posix_memalign", "[newlib_misc]")
|
||||||
@@ -41,6 +42,26 @@ TEST_CASE("misc - posix_memalign", "[newlib_misc]")
|
|||||||
TEST_ASSERT_NOT_NULL(outptr);
|
TEST_ASSERT_NOT_NULL(outptr);
|
||||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||||
free(outptr);
|
free(outptr);
|
||||||
|
|
||||||
|
outptr = magic;
|
||||||
|
heap_caps_malloc_extmem_enable(128);
|
||||||
|
ret = posix_memalign(&outptr, 16, 64);
|
||||||
|
TEST_ASSERT_TRUE(outptr != magic);
|
||||||
|
TEST_ASSERT_NOT_NULL(outptr);
|
||||||
|
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||||
|
free(outptr);
|
||||||
|
|
||||||
|
outptr = magic;
|
||||||
|
heap_caps_malloc_extmem_enable(64);
|
||||||
|
ret = posix_memalign(&outptr, 16, 128);
|
||||||
|
TEST_ASSERT_TRUE(outptr != magic);
|
||||||
|
TEST_ASSERT_NOT_NULL(outptr);
|
||||||
|
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||||
|
free(outptr);
|
||||||
|
|
||||||
|
#if CONFIG_SPIRAM_USE_MALLOC
|
||||||
|
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("misc - sysconf", "[newlib_misc]")
|
TEST_CASE("misc - sysconf", "[newlib_misc]")
|
||||||
|
Reference in New Issue
Block a user