mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Nov 08 11:46:34 2018 +0000
Revision:
188:bcfe06ba3d64
Parent:
187:0387e8f68319
Child:
189:f392fc9709a3
mbed-dev library. Release version 164

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /* mbed Microcontroller Library
<> 149:156823d33999 2 * Copyright (c) 2006-2016 ARM Limited
<> 149:156823d33999 3 *
<> 149:156823d33999 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 149:156823d33999 5 * you may not use this file except in compliance with the License.
<> 149:156823d33999 6 * You may obtain a copy of the License at
<> 149:156823d33999 7 *
<> 149:156823d33999 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 149:156823d33999 9 *
<> 149:156823d33999 10 * Unless required by applicable law or agreed to in writing, software
<> 149:156823d33999 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 149:156823d33999 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 149:156823d33999 13 * See the License for the specific language governing permissions and
<> 149:156823d33999 14 * limitations under the License.
<> 149:156823d33999 15 */
<> 149:156823d33999 16
<> 149:156823d33999 17 #include "platform/mbed_mem_trace.h"
<> 149:156823d33999 18 #include "platform/mbed_stats.h"
<> 160:d5399cc887bb 19 #include "platform/mbed_toolchain.h"
<> 149:156823d33999 20 #include "platform/SingletonPtr.h"
<> 149:156823d33999 21 #include "platform/PlatformMutex.h"
<> 149:156823d33999 22 #include <stddef.h>
<> 149:156823d33999 23 #include <stdio.h>
<> 149:156823d33999 24 #include <string.h>
<> 149:156823d33999 25 #include <stdlib.h>
<> 149:156823d33999 26
<> 149:156823d33999 27 /* There are two memory tracers in mbed OS:
<> 149:156823d33999 28
<> 149:156823d33999 29 - the first can be used to detect the maximum heap usage at runtime. It is
<> 149:156823d33999 30 activated by defining the MBED_HEAP_STATS_ENABLED macro.
<> 149:156823d33999 31 - the second can be used to trace each memory call by automatically invoking
<> 149:156823d33999 32 a callback on each memory operation (see hal/api/mbed_mem_trace.h). It is
AnnaBridge 188:bcfe06ba3d64 33 activated by setting the configuration option MBED_MEM_TRACING_ENABLED to true.
<> 149:156823d33999 34
<> 149:156823d33999 35 Both tracers can be activated and deactivated in any combination. If both tracers
<> 149:156823d33999 36 are active, the second one (MBED_MEM_TRACING_ENABLED) will trace the first one's
<> 149:156823d33999 37 (MBED_HEAP_STATS_ENABLED) memory calls.*/
<> 149:156823d33999 38
<> 149:156823d33999 39 /******************************************************************************/
<> 149:156823d33999 40 /* Implementation of the runtime max heap usage checker */
<> 149:156823d33999 41 /******************************************************************************/
<> 149:156823d33999 42
<> 149:156823d33999 43 typedef struct {
<> 149:156823d33999 44 uint32_t size;
AnnaBridge 188:bcfe06ba3d64 45 uint32_t signature;
<> 149:156823d33999 46 } alloc_info_t;
<> 149:156823d33999 47
<> 149:156823d33999 48 #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 49 #define MBED_HEAP_STATS_SIGNATURE (0xdeadbeef)
AnnaBridge 188:bcfe06ba3d64 50
<> 149:156823d33999 51 static SingletonPtr<PlatformMutex> malloc_stats_mutex;
AnnaBridge 188:bcfe06ba3d64 52 static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0, 0, 0};
AnnaBridge 188:bcfe06ba3d64 53
AnnaBridge 188:bcfe06ba3d64 54 typedef struct {
AnnaBridge 188:bcfe06ba3d64 55 size_t size;
AnnaBridge 188:bcfe06ba3d64 56 }mbed_heap_overhead_t;
AnnaBridge 188:bcfe06ba3d64 57
AnnaBridge 188:bcfe06ba3d64 58 #define MALLOC_HEADER_SIZE (sizeof(mbed_heap_overhead_t))
AnnaBridge 188:bcfe06ba3d64 59 #define MALLOC_HEADER_PTR(p) (mbed_heap_overhead_t *)((char *)(p) - MALLOC_HEADER_SIZE)
AnnaBridge 188:bcfe06ba3d64 60 #define MALLOC_HEAP_TOTAL_SIZE(p) (((p)->size) & (~0x1))
<> 149:156823d33999 61 #endif
<> 149:156823d33999 62
<> 149:156823d33999 63 void mbed_stats_heap_get(mbed_stats_heap_t *stats)
<> 149:156823d33999 64 {
<> 149:156823d33999 65 #ifdef MBED_HEAP_STATS_ENABLED
<> 152:9a67f0b066fc 66 extern uint32_t mbed_heap_size;
<> 152:9a67f0b066fc 67 heap_stats.reserved_size = mbed_heap_size;
<> 152:9a67f0b066fc 68
<> 149:156823d33999 69 malloc_stats_mutex->lock();
<> 149:156823d33999 70 memcpy(stats, &heap_stats, sizeof(mbed_stats_heap_t));
<> 149:156823d33999 71 malloc_stats_mutex->unlock();
<> 149:156823d33999 72 #else
<> 149:156823d33999 73 memset(stats, 0, sizeof(mbed_stats_heap_t));
<> 149:156823d33999 74 #endif
<> 149:156823d33999 75 }
<> 149:156823d33999 76
<> 149:156823d33999 77 /******************************************************************************/
<> 149:156823d33999 78 /* GCC memory allocation wrappers */
<> 149:156823d33999 79 /******************************************************************************/
<> 149:156823d33999 80
<> 149:156823d33999 81 #if defined(TOOLCHAIN_GCC)
<> 149:156823d33999 82
<> 149:156823d33999 83 extern "C" {
AnnaBridge 187:0387e8f68319 84 void *__real__malloc_r(struct _reent *r, size_t size);
AnnaBridge 187:0387e8f68319 85 void *__real__memalign_r(struct _reent *r, size_t alignment, size_t bytes);
AnnaBridge 187:0387e8f68319 86 void *__real__realloc_r(struct _reent *r, void *ptr, size_t size);
AnnaBridge 187:0387e8f68319 87 void __real__free_r(struct _reent *r, void *ptr);
AnnaBridge 187:0387e8f68319 88 void *__real__calloc_r(struct _reent *r, size_t nmemb, size_t size);
AnnaBridge 187:0387e8f68319 89 void *malloc_wrapper(struct _reent *r, size_t size, void *caller);
AnnaBridge 187:0387e8f68319 90 void free_wrapper(struct _reent *r, void *ptr, void *caller);
<> 149:156823d33999 91 }
<> 149:156823d33999 92
<> 149:156823d33999 93
AnnaBridge 187:0387e8f68319 94 extern "C" void *__wrap__malloc_r(struct _reent *r, size_t size)
AnnaBridge 187:0387e8f68319 95 {
AnnaBridge 181:57724642e740 96 return malloc_wrapper(r, size, MBED_CALLER_ADDR());
AnnaBridge 181:57724642e740 97 }
AnnaBridge 181:57724642e740 98
AnnaBridge 187:0387e8f68319 99 extern "C" void *malloc_wrapper(struct _reent *r, size_t size, void *caller)
AnnaBridge 187:0387e8f68319 100 {
<> 149:156823d33999 101 void *ptr = NULL;
AnnaBridge 188:bcfe06ba3d64 102 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 103 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 104 #endif
<> 149:156823d33999 105 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 106 malloc_stats_mutex->lock();
AnnaBridge 187:0387e8f68319 107 alloc_info_t *alloc_info = (alloc_info_t *)__real__malloc_r(r, size + sizeof(alloc_info_t));
<> 149:156823d33999 108 if (alloc_info != NULL) {
<> 149:156823d33999 109 alloc_info->size = size;
AnnaBridge 188:bcfe06ba3d64 110 alloc_info->signature = MBED_HEAP_STATS_SIGNATURE;
AnnaBridge 187:0387e8f68319 111 ptr = (void *)(alloc_info + 1);
<> 149:156823d33999 112 heap_stats.current_size += size;
<> 149:156823d33999 113 heap_stats.total_size += size;
<> 149:156823d33999 114 heap_stats.alloc_cnt += 1;
<> 149:156823d33999 115 if (heap_stats.current_size > heap_stats.max_size) {
<> 149:156823d33999 116 heap_stats.max_size = heap_stats.current_size;
<> 149:156823d33999 117 }
AnnaBridge 188:bcfe06ba3d64 118 heap_stats.overhead_size += MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)) - size;
<> 149:156823d33999 119 } else {
<> 149:156823d33999 120 heap_stats.alloc_fail_cnt += 1;
<> 149:156823d33999 121 }
<> 149:156823d33999 122 malloc_stats_mutex->unlock();
<> 149:156823d33999 123 #else // #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 124 ptr = __real__malloc_r(r, size);
<> 149:156823d33999 125 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 126 #if MBED_MEM_TRACING_ENABLED
AnnaBridge 181:57724642e740 127 mbed_mem_trace_malloc(ptr, size, caller);
Anna Bridge 180:96ed750bd169 128 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 129 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 130 return ptr;
<> 149:156823d33999 131 }
<> 149:156823d33999 132
AnnaBridge 187:0387e8f68319 133 extern "C" void *__wrap__realloc_r(struct _reent *r, void *ptr, size_t size)
AnnaBridge 187:0387e8f68319 134 {
<> 149:156823d33999 135 void *new_ptr = NULL;
AnnaBridge 188:bcfe06ba3d64 136 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 137 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 138 #endif
<> 149:156823d33999 139 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 140 // Implement realloc_r with malloc and free.
<> 149:156823d33999 141 // The function realloc_r can't be used here directly since
<> 149:156823d33999 142 // it can call into __wrap__malloc_r (returns ptr + 4) or
<> 149:156823d33999 143 // resize memory directly (returns ptr + 0).
<> 149:156823d33999 144
<> 149:156823d33999 145 // Note - no lock needed since malloc and free are thread safe
<> 149:156823d33999 146
<> 149:156823d33999 147 // Get old size
<> 149:156823d33999 148 uint32_t old_size = 0;
<> 149:156823d33999 149 if (ptr != NULL) {
AnnaBridge 187:0387e8f68319 150 alloc_info_t *alloc_info = ((alloc_info_t *)ptr) - 1;
<> 149:156823d33999 151 old_size = alloc_info->size;
<> 149:156823d33999 152 }
<> 149:156823d33999 153
<> 149:156823d33999 154 // Allocate space
<> 149:156823d33999 155 if (size != 0) {
<> 149:156823d33999 156 new_ptr = malloc(size);
<> 149:156823d33999 157 }
<> 149:156823d33999 158
<> 149:156823d33999 159 // If the new buffer has been allocated copy the data to it
<> 149:156823d33999 160 // and free the old buffer
<> 149:156823d33999 161 if (new_ptr != NULL) {
<> 149:156823d33999 162 uint32_t copy_size = (old_size < size) ? old_size : size;
AnnaBridge 187:0387e8f68319 163 memcpy(new_ptr, (void *)ptr, copy_size);
<> 149:156823d33999 164 free(ptr);
<> 149:156823d33999 165 }
<> 149:156823d33999 166 #else // #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 167 new_ptr = __real__realloc_r(r, ptr, size);
<> 149:156823d33999 168 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 169 #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 170 mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR());
Anna Bridge 180:96ed750bd169 171 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 172 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 173 return new_ptr;
<> 149:156823d33999 174 }
<> 149:156823d33999 175
AnnaBridge 187:0387e8f68319 176 extern "C" void __wrap__free_r(struct _reent *r, void *ptr)
AnnaBridge 187:0387e8f68319 177 {
AnnaBridge 181:57724642e740 178 free_wrapper(r, ptr, MBED_CALLER_ADDR());
AnnaBridge 181:57724642e740 179 }
AnnaBridge 181:57724642e740 180
AnnaBridge 187:0387e8f68319 181 extern "C" void free_wrapper(struct _reent *r, void *ptr, void *caller)
AnnaBridge 187:0387e8f68319 182 {
AnnaBridge 188:bcfe06ba3d64 183 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 184 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 185 #endif
<> 149:156823d33999 186 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 187 malloc_stats_mutex->lock();
<> 149:156823d33999 188 alloc_info_t *alloc_info = NULL;
<> 149:156823d33999 189 if (ptr != NULL) {
AnnaBridge 187:0387e8f68319 190 alloc_info = ((alloc_info_t *)ptr) - 1;
AnnaBridge 188:bcfe06ba3d64 191 if (MBED_HEAP_STATS_SIGNATURE == alloc_info->signature) {
AnnaBridge 188:bcfe06ba3d64 192 size_t user_size = alloc_info->size;
AnnaBridge 188:bcfe06ba3d64 193 size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info));
AnnaBridge 188:bcfe06ba3d64 194 alloc_info->signature = 0x0;
AnnaBridge 188:bcfe06ba3d64 195 heap_stats.current_size -= user_size;
AnnaBridge 188:bcfe06ba3d64 196 heap_stats.alloc_cnt -= 1;
AnnaBridge 188:bcfe06ba3d64 197 heap_stats.overhead_size -= (alloc_size - user_size);
AnnaBridge 188:bcfe06ba3d64 198 __real__free_r(r, (void *)alloc_info);
AnnaBridge 188:bcfe06ba3d64 199 } else {
AnnaBridge 188:bcfe06ba3d64 200 __real__free_r(r, ptr);
AnnaBridge 188:bcfe06ba3d64 201 }
<> 149:156823d33999 202 }
AnnaBridge 188:bcfe06ba3d64 203
<> 149:156823d33999 204 malloc_stats_mutex->unlock();
<> 149:156823d33999 205 #else // #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 206 __real__free_r(r, ptr);
<> 149:156823d33999 207 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 208 #if MBED_MEM_TRACING_ENABLED
AnnaBridge 181:57724642e740 209 mbed_mem_trace_free(ptr, caller);
Anna Bridge 180:96ed750bd169 210 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 211 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 212 }
<> 149:156823d33999 213
AnnaBridge 187:0387e8f68319 214 extern "C" void *__wrap__calloc_r(struct _reent *r, size_t nmemb, size_t size)
AnnaBridge 187:0387e8f68319 215 {
<> 149:156823d33999 216 void *ptr = NULL;
AnnaBridge 188:bcfe06ba3d64 217 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 218 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 219 #endif
<> 149:156823d33999 220 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 221 // Note - no lock needed since malloc is thread safe
<> 149:156823d33999 222
<> 149:156823d33999 223 ptr = malloc(nmemb * size);
<> 149:156823d33999 224 if (ptr != NULL) {
<> 149:156823d33999 225 memset(ptr, 0, nmemb * size);
<> 149:156823d33999 226 }
<> 149:156823d33999 227 #else // #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 228 ptr = __real__calloc_r(r, nmemb, size);
<> 149:156823d33999 229 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 230 #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 231 mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR());
Anna Bridge 180:96ed750bd169 232 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 233 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 234 return ptr;
<> 149:156823d33999 235 }
<> 149:156823d33999 236
AnnaBridge 187:0387e8f68319 237 extern "C" void *__wrap__memalign_r(struct _reent *r, size_t alignment, size_t bytes)
AnnaBridge 187:0387e8f68319 238 {
AnnaBridge 167:e84263d55307 239 return __real__memalign_r(r, alignment, bytes);
AnnaBridge 167:e84263d55307 240 }
AnnaBridge 167:e84263d55307 241
<> 149:156823d33999 242
<> 149:156823d33999 243 /******************************************************************************/
AnnaBridge 174:b96e65c34a4d 244 /* ARMCC / IAR memory allocation wrappers */
<> 149:156823d33999 245 /******************************************************************************/
<> 149:156823d33999 246
AnnaBridge 174:b96e65c34a4d 247 #elif defined(TOOLCHAIN_ARM) || defined(__ICCARM__)
AnnaBridge 174:b96e65c34a4d 248
AnnaBridge 174:b96e65c34a4d 249 #if defined(TOOLCHAIN_ARM)
AnnaBridge 174:b96e65c34a4d 250 #define SUPER_MALLOC $Super$$malloc
AnnaBridge 174:b96e65c34a4d 251 #define SUB_MALLOC $Sub$$malloc
AnnaBridge 174:b96e65c34a4d 252 #define SUPER_REALLOC $Super$$realloc
AnnaBridge 174:b96e65c34a4d 253 #define SUB_REALLOC $Sub$$realloc
AnnaBridge 174:b96e65c34a4d 254 #define SUPER_CALLOC $Super$$calloc
AnnaBridge 174:b96e65c34a4d 255 #define SUB_CALLOC $Sub$$calloc
AnnaBridge 174:b96e65c34a4d 256 #define SUPER_FREE $Super$$free
AnnaBridge 174:b96e65c34a4d 257 #define SUB_FREE $Sub$$free
AnnaBridge 174:b96e65c34a4d 258 #elif defined(__ICCARM__)
AnnaBridge 174:b96e65c34a4d 259 #define SUPER_MALLOC $Super$$__iar_dlmalloc
AnnaBridge 174:b96e65c34a4d 260 #define SUB_MALLOC $Sub$$__iar_dlmalloc
AnnaBridge 174:b96e65c34a4d 261 #define SUPER_REALLOC $Super$$__iar_dlrealloc
AnnaBridge 174:b96e65c34a4d 262 #define SUB_REALLOC $Sub$$__iar_dlrealloc
AnnaBridge 174:b96e65c34a4d 263 #define SUPER_CALLOC $Super$$__iar_dlcalloc
AnnaBridge 174:b96e65c34a4d 264 #define SUB_CALLOC $Sub$$__iar_dlcalloc
AnnaBridge 174:b96e65c34a4d 265 #define SUPER_FREE $Super$$__iar_dlfree
AnnaBridge 174:b96e65c34a4d 266 #define SUB_FREE $Sub$$__iar_dlfree
AnnaBridge 174:b96e65c34a4d 267 #endif
<> 149:156823d33999 268
<> 149:156823d33999 269 /* Enable hooking of memory function only if tracing is also enabled */
<> 149:156823d33999 270 #if defined(MBED_MEM_TRACING_ENABLED) || defined(MBED_HEAP_STATS_ENABLED)
<> 149:156823d33999 271
<> 149:156823d33999 272 extern "C" {
AnnaBridge 174:b96e65c34a4d 273 void *SUPER_MALLOC(size_t size);
AnnaBridge 174:b96e65c34a4d 274 void *SUPER_REALLOC(void *ptr, size_t size);
AnnaBridge 174:b96e65c34a4d 275 void *SUPER_CALLOC(size_t nmemb, size_t size);
AnnaBridge 174:b96e65c34a4d 276 void SUPER_FREE(void *ptr);
AnnaBridge 187:0387e8f68319 277 void *malloc_wrapper(size_t size, void *caller);
AnnaBridge 187:0387e8f68319 278 void free_wrapper(void *ptr, void *caller);
<> 149:156823d33999 279 }
<> 149:156823d33999 280
AnnaBridge 187:0387e8f68319 281 extern "C" void *SUB_MALLOC(size_t size)
AnnaBridge 187:0387e8f68319 282 {
AnnaBridge 181:57724642e740 283 return malloc_wrapper(size, MBED_CALLER_ADDR());
AnnaBridge 181:57724642e740 284 }
AnnaBridge 181:57724642e740 285
AnnaBridge 187:0387e8f68319 286 extern "C" void *malloc_wrapper(size_t size, void *caller)
AnnaBridge 187:0387e8f68319 287 {
<> 149:156823d33999 288 void *ptr = NULL;
AnnaBridge 188:bcfe06ba3d64 289 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 290 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 291 #endif
<> 149:156823d33999 292 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 293 malloc_stats_mutex->lock();
AnnaBridge 187:0387e8f68319 294 alloc_info_t *alloc_info = (alloc_info_t *)SUPER_MALLOC(size + sizeof(alloc_info_t));
<> 149:156823d33999 295 if (alloc_info != NULL) {
<> 149:156823d33999 296 alloc_info->size = size;
AnnaBridge 188:bcfe06ba3d64 297 alloc_info->signature = MBED_HEAP_STATS_SIGNATURE;
AnnaBridge 187:0387e8f68319 298 ptr = (void *)(alloc_info + 1);
<> 149:156823d33999 299 heap_stats.current_size += size;
<> 149:156823d33999 300 heap_stats.total_size += size;
<> 149:156823d33999 301 heap_stats.alloc_cnt += 1;
<> 149:156823d33999 302 if (heap_stats.current_size > heap_stats.max_size) {
<> 149:156823d33999 303 heap_stats.max_size = heap_stats.current_size;
<> 149:156823d33999 304 }
AnnaBridge 188:bcfe06ba3d64 305 heap_stats.overhead_size += MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)) - size;
<> 149:156823d33999 306 } else {
<> 149:156823d33999 307 heap_stats.alloc_fail_cnt += 1;
<> 149:156823d33999 308 }
<> 149:156823d33999 309 malloc_stats_mutex->unlock();
<> 149:156823d33999 310 #else // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 174:b96e65c34a4d 311 ptr = SUPER_MALLOC(size);
<> 149:156823d33999 312 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 313 #if MBED_MEM_TRACING_ENABLED
AnnaBridge 181:57724642e740 314 mbed_mem_trace_malloc(ptr, size, caller);
Anna Bridge 180:96ed750bd169 315 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 316 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 317 return ptr;
<> 149:156823d33999 318 }
<> 149:156823d33999 319
AnnaBridge 181:57724642e740 320
AnnaBridge 187:0387e8f68319 321 extern "C" void *SUB_REALLOC(void *ptr, size_t size)
AnnaBridge 187:0387e8f68319 322 {
<> 149:156823d33999 323 void *new_ptr = NULL;
AnnaBridge 188:bcfe06ba3d64 324 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 325 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 326 #endif
<> 149:156823d33999 327 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 328 // Note - no lock needed since malloc and free are thread safe
<> 149:156823d33999 329
<> 149:156823d33999 330 // Get old size
<> 149:156823d33999 331 uint32_t old_size = 0;
<> 149:156823d33999 332 if (ptr != NULL) {
AnnaBridge 187:0387e8f68319 333 alloc_info_t *alloc_info = ((alloc_info_t *)ptr) - 1;
<> 149:156823d33999 334 old_size = alloc_info->size;
<> 149:156823d33999 335 }
<> 149:156823d33999 336
<> 149:156823d33999 337 // Allocate space
<> 149:156823d33999 338 if (size != 0) {
<> 149:156823d33999 339 new_ptr = malloc(size);
<> 149:156823d33999 340 }
<> 149:156823d33999 341
<> 149:156823d33999 342 // If the new buffer has been allocated copy the data to it
<> 149:156823d33999 343 // and free the old buffer
AnnaBridge 188:bcfe06ba3d64 344 if ((new_ptr != NULL) && (ptr != NULL)) {
<> 149:156823d33999 345 uint32_t copy_size = (old_size < size) ? old_size : size;
AnnaBridge 187:0387e8f68319 346 memcpy(new_ptr, (void *)ptr, copy_size);
<> 149:156823d33999 347 free(ptr);
<> 149:156823d33999 348 }
<> 149:156823d33999 349 #else // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 174:b96e65c34a4d 350 new_ptr = SUPER_REALLOC(ptr, size);
<> 149:156823d33999 351 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 352 #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 353 mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR());
Anna Bridge 180:96ed750bd169 354 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 355 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 356 return new_ptr;
<> 149:156823d33999 357 }
<> 149:156823d33999 358
AnnaBridge 187:0387e8f68319 359 extern "C" void *SUB_CALLOC(size_t nmemb, size_t size)
AnnaBridge 187:0387e8f68319 360 {
<> 149:156823d33999 361 void *ptr = NULL;
AnnaBridge 188:bcfe06ba3d64 362 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 363 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 364 #endif
<> 149:156823d33999 365 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 366 // Note - no lock needed since malloc is thread safe
<> 149:156823d33999 367 ptr = malloc(nmemb * size);
<> 149:156823d33999 368 if (ptr != NULL) {
<> 149:156823d33999 369 memset(ptr, 0, nmemb * size);
<> 149:156823d33999 370 }
<> 149:156823d33999 371 #else // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 174:b96e65c34a4d 372 ptr = SUPER_CALLOC(nmemb, size);
<> 149:156823d33999 373 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 374 #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 375 mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR());
Anna Bridge 180:96ed750bd169 376 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 377 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 378 return ptr;
<> 149:156823d33999 379 }
<> 149:156823d33999 380
AnnaBridge 187:0387e8f68319 381 extern "C" void SUB_FREE(void *ptr)
AnnaBridge 187:0387e8f68319 382 {
AnnaBridge 181:57724642e740 383 free_wrapper(ptr, MBED_CALLER_ADDR());
AnnaBridge 181:57724642e740 384 }
AnnaBridge 181:57724642e740 385
AnnaBridge 187:0387e8f68319 386 extern "C" void free_wrapper(void *ptr, void *caller)
AnnaBridge 187:0387e8f68319 387 {
AnnaBridge 188:bcfe06ba3d64 388 #if MBED_MEM_TRACING_ENABLED
Anna Bridge 180:96ed750bd169 389 mbed_mem_trace_lock();
Anna Bridge 180:96ed750bd169 390 #endif
<> 149:156823d33999 391 #ifdef MBED_HEAP_STATS_ENABLED
<> 149:156823d33999 392 malloc_stats_mutex->lock();
<> 149:156823d33999 393 alloc_info_t *alloc_info = NULL;
<> 149:156823d33999 394 if (ptr != NULL) {
AnnaBridge 187:0387e8f68319 395 alloc_info = ((alloc_info_t *)ptr) - 1;
AnnaBridge 188:bcfe06ba3d64 396 if (MBED_HEAP_STATS_SIGNATURE == alloc_info->signature) {
AnnaBridge 188:bcfe06ba3d64 397 size_t user_size = alloc_info->size;
AnnaBridge 188:bcfe06ba3d64 398 size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info));
AnnaBridge 188:bcfe06ba3d64 399 alloc_info->signature = 0x0;
AnnaBridge 188:bcfe06ba3d64 400 heap_stats.current_size -= user_size;
AnnaBridge 188:bcfe06ba3d64 401 heap_stats.alloc_cnt -= 1;
AnnaBridge 188:bcfe06ba3d64 402 heap_stats.overhead_size -= (alloc_size - user_size);
AnnaBridge 188:bcfe06ba3d64 403 SUPER_FREE((void *)alloc_info);
AnnaBridge 188:bcfe06ba3d64 404 } else {
AnnaBridge 188:bcfe06ba3d64 405 SUPER_FREE(ptr);
AnnaBridge 188:bcfe06ba3d64 406 }
<> 149:156823d33999 407 }
AnnaBridge 188:bcfe06ba3d64 408
<> 149:156823d33999 409 malloc_stats_mutex->unlock();
<> 149:156823d33999 410 #else // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 174:b96e65c34a4d 411 SUPER_FREE(ptr);
<> 149:156823d33999 412 #endif // #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 188:bcfe06ba3d64 413 #if MBED_MEM_TRACING_ENABLED
AnnaBridge 181:57724642e740 414 mbed_mem_trace_free(ptr, caller);
Anna Bridge 180:96ed750bd169 415 mbed_mem_trace_unlock();
AnnaBridge 188:bcfe06ba3d64 416 #endif // #if MBED_MEM_TRACING_ENABLED
<> 149:156823d33999 417 }
<> 149:156823d33999 418
<> 149:156823d33999 419 #endif // #if defined(MBED_MEM_TRACING_ENABLED) || defined(MBED_HEAP_STATS_ENABLED)
<> 149:156823d33999 420
<> 149:156823d33999 421 /******************************************************************************/
<> 149:156823d33999 422 /* Allocation wrappers for other toolchains are not supported yet */
<> 149:156823d33999 423 /******************************************************************************/
<> 149:156823d33999 424
AnnaBridge 174:b96e65c34a4d 425 #else
<> 149:156823d33999 426
AnnaBridge 188:bcfe06ba3d64 427 #if MBED_MEM_TRACING_ENABLED
AnnaBridge 174:b96e65c34a4d 428 #error Memory tracing is not supported with the current toolchain.
<> 149:156823d33999 429 #endif
<> 149:156823d33999 430
<> 149:156823d33999 431 #ifdef MBED_HEAP_STATS_ENABLED
AnnaBridge 174:b96e65c34a4d 432 #error Heap statistics are not supported with the current toolchain.
<> 149:156823d33999 433 #endif
<> 149:156823d33999 434
<> 149:156823d33999 435 #endif // #if defined(TOOLCHAIN_GCC)