Skip to content

Commit

Permalink
Merge branch 'feat/sort-heaps-by-size' into 'master'
Browse files Browse the repository at this point in the history
feat(heap): Sort list of registered heap by increasing size

Closes IDFGH-12587

See merge request espressif/esp-idf!33572
  • Loading branch information
SoucheSouche committed Nov 25, 2024
2 parents 56a55c0 + 2a9a418 commit ab3d179
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion components/esp_psram/test_apps/psram/main/test_app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
49 changes: 44 additions & 5 deletions components/heap/heap_caps_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(&registered_heaps)) {
SLIST_INSERT_HEAD(&registered_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, &registered_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(&registered_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;
Expand Down Expand Up @@ -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(&registered_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]);
}
}

Expand Down

0 comments on commit ab3d179

Please sign in to comment.