From fc1e8b036546326c2ece3d1d498c6155eb85171e Mon Sep 17 00:00:00 2001 From: Chip Weinberger Date: Thu, 25 May 2023 22:05:07 -0700 Subject: [PATCH 1/3] [Heap Trace Standalone] do not allocate memory until init is called --- components/heap/Kconfig | 29 +++++++++---------- components/heap/heap_trace_standalone.c | 29 +++++++++++++------ .../sdkconfig.ci.heap_trace_hashmap | 1 - 3 files changed, 33 insertions(+), 26 deletions(-) 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 From 185d7a7bd4a9a384f65d01b91410e6b3bdbaad7a Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 30 May 2023 11:40:17 +0800 Subject: [PATCH 2/3] heap: fixed unused variable warning --- components/heap/heap_trace_standalone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/heap/heap_trace_standalone.c b/components/heap/heap_trace_standalone.c index 53ba9553b3..4a01d5e024 100644 --- a/components/heap/heap_trace_standalone.c +++ b/components/heap/heap_trace_standalone.c @@ -18,7 +18,7 @@ #include "esp_memory_utils.h" #include "sys/queue.h" -static const char* TAG = "heaptrace"; +static __attribute__((unused)) const char* TAG = "heaptrace"; #define STACK_DEPTH CONFIG_HEAP_TRACING_STACK_DEPTH From 450618c39df5b64877570f0ef613b87c1e609c40 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Fri, 7 Jul 2023 10:49:15 +0800 Subject: [PATCH 3/3] docs(heap): fixed typo in heap trace docs --- components/heap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/heap/Kconfig b/components/heap/Kconfig index 57fe0d8eaa..f1a382be9e 100644 --- a/components/heap/Kconfig +++ b/components/heap/Kconfig @@ -81,7 +81,7 @@ menu "Heap memory debugging" 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. + list grows. This is particularly affected when using 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.