diff --git a/components/esp_hw_support/test_apps/dma/main/test_app_main.c b/components/esp_hw_support/test_apps/dma/main/test_app_main.c index 311f7bbb72..6235df9f3d 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_app_main.c +++ b/components/esp_hw_support/test_apps/dma/main/test_app_main.c @@ -9,7 +9,7 @@ #include "esp_heap_caps.h" // Some resources are lazy allocated in pulse_cnt driver, the threshold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (-300) +#define TEST_MEMORY_LEAK_THRESHOLD (-400) static size_t before_free_8bit; static size_t before_free_32bit; diff --git a/components/esp_psram/test_apps/psram/main/test_app_main.c b/components/esp_psram/test_apps/psram/main/test_app_main.c index e19a4c2c37..8ca8bacf7e 100644 --- a/components/esp_psram/test_apps/psram/main/test_app_main.c +++ b/components/esp_psram/test_apps/psram/main/test_app_main.c @@ -8,7 +8,7 @@ #include "unity_test_runner.h" #include "esp_heap_caps.h" -#define TEST_MEMORY_LEAK_THRESHOLD (-600) +#define TEST_MEMORY_LEAK_THRESHOLD (-700) static size_t before_free_8bit; static size_t before_free_32bit; diff --git a/components/heap/heap_caps_init.c b/components/heap/heap_caps_init.c index 22e0b2436d..67c6d911bb 100644 --- a/components/heap/heap_caps_init.c +++ b/components/heap/heap_caps_init.c @@ -27,6 +27,43 @@ ESP_SYSTEM_INIT_FN(init_heap, CORE, BIT(0), 100) return ESP_OK; } +/** + * @brief This helper function adds a new heap to list of registered + * heaps making sure to keep the heaps sorted by ascending size. + * + * @param new_heap heap to be inserted in the list of registered + * heaps + */ +static void sorted_add_to_registered_heaps(heap_t *new_heap) +{ + // if list empty, insert head and return + if (SLIST_EMPTY(®istered_heaps)) { + SLIST_INSERT_HEAD(®istered_heaps, new_heap, next); + return; + } + + // else, go through the registered heaps and add the new one + // so the registered heaps are sorted by increasing heap size. + heap_t *cur_heap = NULL; + heap_t *prev_heap = NULL; + const size_t new_heap_size = new_heap->end - new_heap->start; + SLIST_FOREACH(cur_heap, ®istered_heaps, next) { + const size_t cur_heap_size = cur_heap->end - cur_heap->start; + if (cur_heap_size >= new_heap_size) { + if (prev_heap != NULL) { + SLIST_INSERT_AFTER(prev_heap, new_heap, next); + } else { + SLIST_INSERT_HEAD(®istered_heaps, new_heap, next); + } + return; + } + prev_heap = cur_heap; + } + + // new heap size if the biggest so far, insert it at the end + SLIST_INSERT_AFTER(prev_heap, new_heap, next); +} + static void register_heap(heap_t *region) { size_t heap_size = region->end - region->start; @@ -154,11 +191,13 @@ void heap_caps_init(void) if (heaps_array[i].heap != NULL) { multi_heap_set_lock(heaps_array[i].heap, &heaps_array[i].heap_mux); } - if (i == 0) { - SLIST_INSERT_HEAD(®istered_heaps, &heaps_array[0], next); - } else { - SLIST_INSERT_AFTER(&heaps_array[i-1], &heaps_array[i], next); - } + /* Since the registered heaps list is always traversed from head + * to tail when looking for a suitable heap when allocating memory, it is + * best to place smaller heap first. In that way, if several heaps share + * the same set of capabilities, the smallest heaps will be used first when + * processing small allocation requests, leaving the bigger heaps untouched + * until the smaller heaps are full. */ + sorted_add_to_registered_heaps(&heaps_array[i]); } }