mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

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