mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: platform/mbed_alloc_wrappers.cpp
- Revision:
- 188:bcfe06ba3d64
- Parent:
- 187:0387e8f68319
- Child:
- 189:f392fc9709a3
--- a/platform/mbed_alloc_wrappers.cpp Thu Sep 06 13:40:20 2018 +0100 +++ b/platform/mbed_alloc_wrappers.cpp Thu Nov 08 11:46:34 2018 +0000 @@ -30,7 +30,7 @@ activated by defining the MBED_HEAP_STATS_ENABLED macro. - the second can be used to trace each memory call by automatically invoking a callback on each memory operation (see hal/api/mbed_mem_trace.h). It is - activated by defining the MBED_MEM_TRACING_ENABLED macro. + activated by setting the configuration option MBED_MEM_TRACING_ENABLED to true. Both tracers can be activated and deactivated in any combination. If both tracers are active, the second one (MBED_MEM_TRACING_ENABLED) will trace the first one's @@ -40,15 +40,24 @@ /* Implementation of the runtime max heap usage checker */ /******************************************************************************/ -/* Size must be a multiple of 8 to keep alignment */ typedef struct { uint32_t size; - uint32_t pad; + uint32_t signature; } alloc_info_t; #ifdef MBED_HEAP_STATS_ENABLED +#define MBED_HEAP_STATS_SIGNATURE (0xdeadbeef) + static SingletonPtr<PlatformMutex> malloc_stats_mutex; -static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0}; +static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0, 0, 0}; + +typedef struct { + size_t size; +}mbed_heap_overhead_t; + +#define MALLOC_HEADER_SIZE (sizeof(mbed_heap_overhead_t)) +#define MALLOC_HEADER_PTR(p) (mbed_heap_overhead_t *)((char *)(p) - MALLOC_HEADER_SIZE) +#define MALLOC_HEAP_TOTAL_SIZE(p) (((p)->size) & (~0x1)) #endif void mbed_stats_heap_get(mbed_stats_heap_t *stats) @@ -71,10 +80,6 @@ #if defined(TOOLCHAIN_GCC) -#ifdef FEATURE_UVISOR -#include "uvisor-lib/uvisor-lib.h" -#endif/* FEATURE_UVISOR */ - extern "C" { void *__real__malloc_r(struct _reent *r, size_t size); void *__real__memalign_r(struct _reent *r, size_t alignment, size_t bytes); @@ -85,8 +90,6 @@ void free_wrapper(struct _reent *r, void *ptr, void *caller); } -// TODO: memory tracing doesn't work with uVisor enabled. -#if !defined(FEATURE_UVISOR) extern "C" void *__wrap__malloc_r(struct _reent *r, size_t size) { @@ -96,7 +99,7 @@ extern "C" void *malloc_wrapper(struct _reent *r, size_t size, void *caller) { void *ptr = NULL; -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -104,6 +107,7 @@ alloc_info_t *alloc_info = (alloc_info_t *)__real__malloc_r(r, size + sizeof(alloc_info_t)); if (alloc_info != NULL) { alloc_info->size = size; + alloc_info->signature = MBED_HEAP_STATS_SIGNATURE; ptr = (void *)(alloc_info + 1); heap_stats.current_size += size; heap_stats.total_size += size; @@ -111,6 +115,7 @@ if (heap_stats.current_size > heap_stats.max_size) { heap_stats.max_size = heap_stats.current_size; } + heap_stats.overhead_size += MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)) - size; } else { heap_stats.alloc_fail_cnt += 1; } @@ -118,17 +123,17 @@ #else // #ifdef MBED_HEAP_STATS_ENABLED ptr = __real__malloc_r(r, size); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_malloc(ptr, size, caller); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED return ptr; } extern "C" void *__wrap__realloc_r(struct _reent *r, void *ptr, size_t size) { void *new_ptr = NULL; -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -161,10 +166,10 @@ #else // #ifdef MBED_HEAP_STATS_ENABLED new_ptr = __real__realloc_r(r, ptr, size); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR()); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED return new_ptr; } @@ -175,7 +180,7 @@ extern "C" void free_wrapper(struct _reent *r, void *ptr, void *caller) { -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -183,24 +188,33 @@ alloc_info_t *alloc_info = NULL; if (ptr != NULL) { alloc_info = ((alloc_info_t *)ptr) - 1; - heap_stats.current_size -= alloc_info->size; - heap_stats.alloc_cnt -= 1; + if (MBED_HEAP_STATS_SIGNATURE == alloc_info->signature) { + size_t user_size = alloc_info->size; + size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)); + alloc_info->signature = 0x0; + heap_stats.current_size -= user_size; + heap_stats.alloc_cnt -= 1; + heap_stats.overhead_size -= (alloc_size - user_size); + __real__free_r(r, (void *)alloc_info); + } else { + __real__free_r(r, ptr); + } } - __real__free_r(r, (void *)alloc_info); + malloc_stats_mutex->unlock(); #else // #ifdef MBED_HEAP_STATS_ENABLED __real__free_r(r, ptr); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_free(ptr, caller); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED } extern "C" void *__wrap__calloc_r(struct _reent *r, size_t nmemb, size_t size) { void *ptr = NULL; -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -213,10 +227,10 @@ #else // #ifdef MBED_HEAP_STATS_ENABLED ptr = __real__calloc_r(r, nmemb, size); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR()); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED return ptr; } @@ -225,8 +239,6 @@ return __real__memalign_r(r, alignment, bytes); } -#endif // if !defined(FEATURE_UVISOR) - /******************************************************************************/ /* ARMCC / IAR memory allocation wrappers */ @@ -266,7 +278,6 @@ void free_wrapper(void *ptr, void *caller); } - extern "C" void *SUB_MALLOC(size_t size) { return malloc_wrapper(size, MBED_CALLER_ADDR()); @@ -275,7 +286,7 @@ extern "C" void *malloc_wrapper(size_t size, void *caller) { void *ptr = NULL; -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -283,6 +294,7 @@ alloc_info_t *alloc_info = (alloc_info_t *)SUPER_MALLOC(size + sizeof(alloc_info_t)); if (alloc_info != NULL) { alloc_info->size = size; + alloc_info->signature = MBED_HEAP_STATS_SIGNATURE; ptr = (void *)(alloc_info + 1); heap_stats.current_size += size; heap_stats.total_size += size; @@ -290,6 +302,7 @@ if (heap_stats.current_size > heap_stats.max_size) { heap_stats.max_size = heap_stats.current_size; } + heap_stats.overhead_size += MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)) - size; } else { heap_stats.alloc_fail_cnt += 1; } @@ -297,10 +310,10 @@ #else // #ifdef MBED_HEAP_STATS_ENABLED ptr = SUPER_MALLOC(size); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_malloc(ptr, size, caller); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED return ptr; } @@ -308,7 +321,7 @@ extern "C" void *SUB_REALLOC(void *ptr, size_t size) { void *new_ptr = NULL; -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -328,7 +341,7 @@ // If the new buffer has been allocated copy the data to it // and free the old buffer - if (new_ptr != NULL) { + if ((new_ptr != NULL) && (ptr != NULL)) { uint32_t copy_size = (old_size < size) ? old_size : size; memcpy(new_ptr, (void *)ptr, copy_size); free(ptr); @@ -336,17 +349,17 @@ #else // #ifdef MBED_HEAP_STATS_ENABLED new_ptr = SUPER_REALLOC(ptr, size); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR()); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED return new_ptr; } extern "C" void *SUB_CALLOC(size_t nmemb, size_t size) { void *ptr = NULL; -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -358,10 +371,10 @@ #else // #ifdef MBED_HEAP_STATS_ENABLED ptr = SUPER_CALLOC(nmemb, size); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR()); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED return ptr; } @@ -372,7 +385,7 @@ extern "C" void free_wrapper(void *ptr, void *caller) { -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_lock(); #endif #ifdef MBED_HEAP_STATS_ENABLED @@ -380,18 +393,27 @@ alloc_info_t *alloc_info = NULL; if (ptr != NULL) { alloc_info = ((alloc_info_t *)ptr) - 1; - heap_stats.current_size -= alloc_info->size; - heap_stats.alloc_cnt -= 1; + if (MBED_HEAP_STATS_SIGNATURE == alloc_info->signature) { + size_t user_size = alloc_info->size; + size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)); + alloc_info->signature = 0x0; + heap_stats.current_size -= user_size; + heap_stats.alloc_cnt -= 1; + heap_stats.overhead_size -= (alloc_size - user_size); + SUPER_FREE((void *)alloc_info); + } else { + SUPER_FREE(ptr); + } } - SUPER_FREE((void *)alloc_info); + malloc_stats_mutex->unlock(); #else // #ifdef MBED_HEAP_STATS_ENABLED SUPER_FREE(ptr); #endif // #ifdef MBED_HEAP_STATS_ENABLED -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED mbed_mem_trace_free(ptr, caller); mbed_mem_trace_unlock(); -#endif // #ifdef MBED_MEM_TRACING_ENABLED +#endif // #if MBED_MEM_TRACING_ENABLED } #endif // #if defined(MBED_MEM_TRACING_ENABLED) || defined(MBED_HEAP_STATS_ENABLED) @@ -402,7 +424,7 @@ #else -#ifdef MBED_MEM_TRACING_ENABLED +#if MBED_MEM_TRACING_ENABLED #error Memory tracing is not supported with the current toolchain. #endif