diff --git a/components/heap/Kconfig b/components/heap/Kconfig index ce47cbfa75..57fe0d8eaa 100644 --- a/components/heap/Kconfig +++ b/components/heap/Kconfig @@ -78,31 +78,28 @@ menu "Heap memory debugging" Enable this flag to use a hash map to increase performance in handling heap trace records. - Keeping this as "n" in your project will save RAM and heap memory but will lower - the performance of the heap trace in adding, retrieving and removing trace records. - Making this as "y" in your project, you will decrease free RAM and heap memory but, - the heap trace performances in adding retrieving and removing trace records will be - enhanced. + Heap trace standalone supports storing records as a list, or a list + hash map. + + Using only a list takes less memory, but calls to 'free' will get slower as the + list grows. This is particiularly affected by HEAP_TRACE_ALL mode. + + By using a list + hash map, calls to 'free' remain fast, at the cost of + additional memory to store the hash map. config HEAP_TRACE_HASH_MAP_IN_EXT_RAM - bool "Place hash map in the bss section of the external RAM" - depends on HEAP_TRACE_HASH_MAP && SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + bool "Place hash map in external RAM" + depends on HEAP_TRACE_HASH_MAP default n help - When enabled this configuration forces the hash map to be placed in the bss section - of the external RAM. - - Note that this functionality can only be enabled when CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - is enabled. + When enabled this configuration forces the hash map to be placed in external RAM. config HEAP_TRACE_HASH_MAP_SIZE int "The number of entries in the hash map" depends on HEAP_TRACE_HASH_MAP - default 10 + default 512 help - Defines the number of entries in the heap trace hashmap. The bigger this number is, - the bigger the hash map will be in the memory. In case the tracing mode is set to - HEAP_TRACE_ALL, the bigger the hashmap is, the better the performances are. + Defines the number of entries in the heap trace hashmap. Each entry takes 8 bytes. + The bigger this number is, the better the performance. Recommended range: 200 - 2000. config HEAP_ABORT_WHEN_ALLOCATION_FAILS bool "Abort if memory allocation fails" diff --git a/components/heap/heap_trace_standalone.c b/components/heap/heap_trace_standalone.c index be5b656793..53ba9553b3 100644 --- a/components/heap/heap_trace_standalone.c +++ b/components/heap/heap_trace_standalone.c @@ -6,6 +6,7 @@ #include #include #include +#include "esp_log.h" #define HEAP_TRACE_SRCFILE /* don't warn on inclusion here */ #include "esp_heap_trace.h" @@ -17,6 +18,8 @@ #include "esp_memory_utils.h" #include "sys/queue.h" +static const char* TAG = "heaptrace"; + #define STACK_DEPTH CONFIG_HEAP_TRACING_STACK_DEPTH #if CONFIG_HEAP_TRACING_STANDALONE @@ -80,15 +83,10 @@ static size_t r_get_idx; #if CONFIG_HEAP_TRACE_HASH_MAP -/* Define struct: linked list of records used in hash map */ -TAILQ_HEAD(heap_trace_hash_list_struct_t, heap_trace_record_t); -typedef struct heap_trace_hash_list_struct_t heap_trace_hash_list_t; - -static -#if CONFIG_HEAP_TRACE_HASH_MAP_IN_EXT_RAM -EXT_RAM_BSS_ATTR -#endif -heap_trace_hash_list_t hash_map[(size_t)CONFIG_HEAP_TRACE_HASH_MAP_SIZE]; // Buffer used for hashmap entries +// We use a hash_map to make locating a record by memory address very fast. +// Key: addr // the memory address returned by malloc, calloc, realloc +// Value: hash_map[hash(key)] // a list of records ptrs, which contains the relevant record. +static heap_trace_record_list_t* hash_map; // array of lists static size_t total_hashmap_hits; static size_t total_hashmap_miss; @@ -140,6 +138,19 @@ esp_err_t heap_trace_init_standalone(heap_trace_record_t *record_buffer, size_t return ESP_ERR_INVALID_ARG; } +#if CONFIG_HEAP_TRACE_HASH_MAP + if (hash_map == NULL) { + uint32_t map_size = sizeof(heap_trace_record_list_t) * CONFIG_HEAP_TRACE_HASH_MAP_SIZE; +#if CONFIG_HEAP_TRACE_HASH_MAP_IN_EXT_RAM + ESP_LOGI(TAG, "hashmap: allocating %" PRIu32 " bytes (PSRAM)\n", map_size); + hash_map = heap_caps_calloc(1, map_size, MALLOC_CAP_SPIRAM); +#else + ESP_LOGI(TAG, "hashmap: allocating %" PRIu32 " bytes (Internal RAM)\n", map_size); + hash_map = heap_caps_calloc(1, map_size, MALLOC_CAP_INTERNAL); +#endif // CONFIG_HEAP_TRACE_HASH_MAP_IN_EXT_RAM + } +#endif // CONFIG_HEAP_TRACE_HASH_MAP + records.buffer = record_buffer; records.capacity = num_records; diff --git a/components/heap/test_apps/heap_tests/sdkconfig.ci.heap_trace_hashmap b/components/heap/test_apps/heap_tests/sdkconfig.ci.heap_trace_hashmap index 72ba9e16f7..26ffa6c779 100644 --- a/components/heap/test_apps/heap_tests/sdkconfig.ci.heap_trace_hashmap +++ b/components/heap/test_apps/heap_tests/sdkconfig.ci.heap_trace_hashmap @@ -1,6 +1,5 @@ CONFIG_IDF_TARGET="esp32" CONFIG_SPIRAM=y -CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y CONFIG_HEAP_TRACING_STANDALONE=y CONFIG_HEAP_TRACE_HASH_MAP=y CONFIG_HEAP_TRACE_HASH_MAP_IN_EXT_RAM=y