Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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


