,,

Fork of Application by Daniel Sygut

Committer:
Zaitsev
Date:
Thu Feb 15 14:29:23 2018 +0000
Revision:
15:2a20c3d2616e
Parent:
10:41552d038a69
j

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Zaitsev 10:41552d038a69 1 /* mbed Microcontroller Library
Zaitsev 10:41552d038a69 2 * Copyright (c) 2006-2016 ARM Limited
Zaitsev 10:41552d038a69 3 *
Zaitsev 10:41552d038a69 4 * Licensed under the Apache License, Version 2.0 (the "License");
Zaitsev 10:41552d038a69 5 * you may not use this file except in compliance with the License.
Zaitsev 10:41552d038a69 6 * You may obtain a copy of the License at
Zaitsev 10:41552d038a69 7 *
Zaitsev 10:41552d038a69 8 * http://www.apache.org/licenses/LICENSE-2.0
Zaitsev 10:41552d038a69 9 *
Zaitsev 10:41552d038a69 10 * Unless required by applicable law or agreed to in writing, software
Zaitsev 10:41552d038a69 11 * distributed under the License is distributed on an "AS IS" BASIS,
Zaitsev 10:41552d038a69 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Zaitsev 10:41552d038a69 13 * See the License for the specific language governing permissions and
Zaitsev 10:41552d038a69 14 * limitations under the License.
Zaitsev 10:41552d038a69 15 */
Zaitsev 10:41552d038a69 16
Zaitsev 10:41552d038a69 17 #include "platform/mbed_mem_trace.h"
Zaitsev 10:41552d038a69 18 #include "platform/mbed_stats.h"
Zaitsev 10:41552d038a69 19 #include "platform/toolchain.h"
Zaitsev 10:41552d038a69 20 #include "platform/SingletonPtr.h"
Zaitsev 10:41552d038a69 21 #include "platform/PlatformMutex.h"
Zaitsev 10:41552d038a69 22 #include <stddef.h>
Zaitsev 10:41552d038a69 23 #include <stdio.h>
Zaitsev 10:41552d038a69 24 #include <string.h>
Zaitsev 10:41552d038a69 25 #include <stdlib.h>
Zaitsev 10:41552d038a69 26
Zaitsev 10:41552d038a69 27 /* There are two memory tracers in mbed OS:
Zaitsev 10:41552d038a69 28
Zaitsev 10:41552d038a69 29 - the first can be used to detect the maximum heap usage at runtime. It is
Zaitsev 10:41552d038a69 30 activated by defining the MBED_HEAP_STATS_ENABLED macro.
Zaitsev 10:41552d038a69 31 - the second can be used to trace each memory call by automatically invoking
Zaitsev 10:41552d038a69 32 a callback on each memory operation (see hal/api/mbed_mem_trace.h). It is
Zaitsev 10:41552d038a69 33 activated by defining the MBED_MEM_TRACING_ENABLED macro.
Zaitsev 10:41552d038a69 34
Zaitsev 10:41552d038a69 35 Both tracers can be activated and deactivated in any combination. If both tracers
Zaitsev 10:41552d038a69 36 are active, the second one (MBED_MEM_TRACING_ENABLED) will trace the first one's
Zaitsev 10:41552d038a69 37 (MBED_HEAP_STATS_ENABLED) memory calls.*/
Zaitsev 10:41552d038a69 38
Zaitsev 10:41552d038a69 39 /******************************************************************************/
Zaitsev 10:41552d038a69 40 /* Implementation of the runtime max heap usage checker */
Zaitsev 10:41552d038a69 41 /******************************************************************************/
Zaitsev 10:41552d038a69 42
Zaitsev 10:41552d038a69 43 /* Size must be a multiple of 8 to keep alignment */
Zaitsev 10:41552d038a69 44 typedef struct {
Zaitsev 10:41552d038a69 45 uint32_t size;
Zaitsev 10:41552d038a69 46 uint32_t pad;
Zaitsev 10:41552d038a69 47 } alloc_info_t;
Zaitsev 10:41552d038a69 48
Zaitsev 10:41552d038a69 49 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 50 static SingletonPtr<PlatformMutex> mem_trace_mutex;
Zaitsev 10:41552d038a69 51 #endif
Zaitsev 10:41552d038a69 52 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 53 static SingletonPtr<PlatformMutex> malloc_stats_mutex;
Zaitsev 10:41552d038a69 54 static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0};
Zaitsev 10:41552d038a69 55 #endif
Zaitsev 10:41552d038a69 56
Zaitsev 10:41552d038a69 57 void mbed_stats_heap_get(mbed_stats_heap_t *stats)
Zaitsev 10:41552d038a69 58 {
Zaitsev 10:41552d038a69 59 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 60 extern uint32_t mbed_heap_size;
Zaitsev 10:41552d038a69 61 heap_stats.reserved_size = mbed_heap_size;
Zaitsev 10:41552d038a69 62
Zaitsev 10:41552d038a69 63 malloc_stats_mutex->lock();
Zaitsev 10:41552d038a69 64 memcpy(stats, &heap_stats, sizeof(mbed_stats_heap_t));
Zaitsev 10:41552d038a69 65 malloc_stats_mutex->unlock();
Zaitsev 10:41552d038a69 66 #else
Zaitsev 10:41552d038a69 67 memset(stats, 0, sizeof(mbed_stats_heap_t));
Zaitsev 10:41552d038a69 68 #endif
Zaitsev 10:41552d038a69 69 }
Zaitsev 10:41552d038a69 70
Zaitsev 10:41552d038a69 71 /******************************************************************************/
Zaitsev 10:41552d038a69 72 /* GCC memory allocation wrappers */
Zaitsev 10:41552d038a69 73 /******************************************************************************/
Zaitsev 10:41552d038a69 74
Zaitsev 10:41552d038a69 75 #if defined(TOOLCHAIN_GCC)
Zaitsev 10:41552d038a69 76
Zaitsev 10:41552d038a69 77 #ifdef FEATURE_UVISOR
Zaitsev 10:41552d038a69 78 #include "uvisor-lib/uvisor-lib.h"
Zaitsev 10:41552d038a69 79 #endif/* FEATURE_UVISOR */
Zaitsev 10:41552d038a69 80
Zaitsev 10:41552d038a69 81 extern "C" {
Zaitsev 10:41552d038a69 82 void * __real__malloc_r(struct _reent * r, size_t size);
Zaitsev 10:41552d038a69 83 void * __real__realloc_r(struct _reent * r, void * ptr, size_t size);
Zaitsev 10:41552d038a69 84 void __real__free_r(struct _reent * r, void * ptr);
Zaitsev 10:41552d038a69 85 void* __real__calloc_r(struct _reent * r, size_t nmemb, size_t size);
Zaitsev 10:41552d038a69 86 }
Zaitsev 10:41552d038a69 87
Zaitsev 10:41552d038a69 88 // TODO: memory tracing doesn't work with uVisor enabled.
Zaitsev 10:41552d038a69 89 #if !defined(FEATURE_UVISOR)
Zaitsev 10:41552d038a69 90
Zaitsev 10:41552d038a69 91 extern "C" void * __wrap__malloc_r(struct _reent * r, size_t size) {
Zaitsev 10:41552d038a69 92 void *ptr = NULL;
Zaitsev 10:41552d038a69 93 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 94 malloc_stats_mutex->lock();
Zaitsev 10:41552d038a69 95 alloc_info_t *alloc_info = (alloc_info_t*)__real__malloc_r(r, size + sizeof(alloc_info_t));
Zaitsev 10:41552d038a69 96 if (alloc_info != NULL) {
Zaitsev 10:41552d038a69 97 alloc_info->size = size;
Zaitsev 10:41552d038a69 98 ptr = (void*)(alloc_info + 1);
Zaitsev 10:41552d038a69 99 heap_stats.current_size += size;
Zaitsev 10:41552d038a69 100 heap_stats.total_size += size;
Zaitsev 10:41552d038a69 101 heap_stats.alloc_cnt += 1;
Zaitsev 10:41552d038a69 102 if (heap_stats.current_size > heap_stats.max_size) {
Zaitsev 10:41552d038a69 103 heap_stats.max_size = heap_stats.current_size;
Zaitsev 10:41552d038a69 104 }
Zaitsev 10:41552d038a69 105 } else {
Zaitsev 10:41552d038a69 106 heap_stats.alloc_fail_cnt += 1;
Zaitsev 10:41552d038a69 107 }
Zaitsev 10:41552d038a69 108 malloc_stats_mutex->unlock();
Zaitsev 10:41552d038a69 109 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 110 ptr = __real__malloc_r(r, size);
Zaitsev 10:41552d038a69 111 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 112 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 113 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 114 mbed_mem_trace_malloc(ptr, size, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 115 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 116 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 117 return ptr;
Zaitsev 10:41552d038a69 118 }
Zaitsev 10:41552d038a69 119
Zaitsev 10:41552d038a69 120 extern "C" void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size) {
Zaitsev 10:41552d038a69 121 void *new_ptr = NULL;
Zaitsev 10:41552d038a69 122 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 123 // Implement realloc_r with malloc and free.
Zaitsev 10:41552d038a69 124 // The function realloc_r can't be used here directly since
Zaitsev 10:41552d038a69 125 // it can call into __wrap__malloc_r (returns ptr + 4) or
Zaitsev 10:41552d038a69 126 // resize memory directly (returns ptr + 0).
Zaitsev 10:41552d038a69 127
Zaitsev 10:41552d038a69 128 // Note - no lock needed since malloc and free are thread safe
Zaitsev 10:41552d038a69 129
Zaitsev 10:41552d038a69 130 // Get old size
Zaitsev 10:41552d038a69 131 uint32_t old_size = 0;
Zaitsev 10:41552d038a69 132 if (ptr != NULL) {
Zaitsev 10:41552d038a69 133 alloc_info_t *alloc_info = ((alloc_info_t*)ptr) - 1;
Zaitsev 10:41552d038a69 134 old_size = alloc_info->size;
Zaitsev 10:41552d038a69 135 }
Zaitsev 10:41552d038a69 136
Zaitsev 10:41552d038a69 137 // Allocate space
Zaitsev 10:41552d038a69 138 if (size != 0) {
Zaitsev 10:41552d038a69 139 new_ptr = malloc(size);
Zaitsev 10:41552d038a69 140 }
Zaitsev 10:41552d038a69 141
Zaitsev 10:41552d038a69 142 // If the new buffer has been allocated copy the data to it
Zaitsev 10:41552d038a69 143 // and free the old buffer
Zaitsev 10:41552d038a69 144 if (new_ptr != NULL) {
Zaitsev 10:41552d038a69 145 uint32_t copy_size = (old_size < size) ? old_size : size;
Zaitsev 10:41552d038a69 146 memcpy(new_ptr, (void*)ptr, copy_size);
Zaitsev 10:41552d038a69 147 free(ptr);
Zaitsev 10:41552d038a69 148 }
Zaitsev 10:41552d038a69 149 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 150 new_ptr = __real__realloc_r(r, ptr, size);
Zaitsev 10:41552d038a69 151 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 152 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 153 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 154 mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 155 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 156 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 157 return new_ptr;
Zaitsev 10:41552d038a69 158 }
Zaitsev 10:41552d038a69 159
Zaitsev 10:41552d038a69 160 extern "C" void __wrap__free_r(struct _reent * r, void * ptr) {
Zaitsev 10:41552d038a69 161 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 162 malloc_stats_mutex->lock();
Zaitsev 10:41552d038a69 163 alloc_info_t *alloc_info = NULL;
Zaitsev 10:41552d038a69 164 if (ptr != NULL) {
Zaitsev 10:41552d038a69 165 alloc_info = ((alloc_info_t*)ptr) - 1;
Zaitsev 10:41552d038a69 166 heap_stats.current_size -= alloc_info->size;
Zaitsev 10:41552d038a69 167 heap_stats.alloc_cnt -= 1;
Zaitsev 10:41552d038a69 168 }
Zaitsev 10:41552d038a69 169 __real__free_r(r, (void*)alloc_info);
Zaitsev 10:41552d038a69 170 malloc_stats_mutex->unlock();
Zaitsev 10:41552d038a69 171 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 172 __real__free_r(r, ptr);
Zaitsev 10:41552d038a69 173 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 174 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 175 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 176 mbed_mem_trace_free(ptr, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 177 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 178 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 179 }
Zaitsev 10:41552d038a69 180
Zaitsev 10:41552d038a69 181 #endif // if !defined(FEATURE_UVISOR)
Zaitsev 10:41552d038a69 182
Zaitsev 10:41552d038a69 183 extern "C" void * __wrap__calloc_r(struct _reent * r, size_t nmemb, size_t size) {
Zaitsev 10:41552d038a69 184 void *ptr = NULL;
Zaitsev 10:41552d038a69 185 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 186 // Note - no lock needed since malloc is thread safe
Zaitsev 10:41552d038a69 187
Zaitsev 10:41552d038a69 188 ptr = malloc(nmemb * size);
Zaitsev 10:41552d038a69 189 if (ptr != NULL) {
Zaitsev 10:41552d038a69 190 memset(ptr, 0, nmemb * size);
Zaitsev 10:41552d038a69 191 }
Zaitsev 10:41552d038a69 192 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 193 ptr = __real__calloc_r(r, nmemb, size);
Zaitsev 10:41552d038a69 194 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 195 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 196 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 197 mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 198 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 199 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 200 return ptr;
Zaitsev 10:41552d038a69 201 }
Zaitsev 10:41552d038a69 202
Zaitsev 10:41552d038a69 203
Zaitsev 10:41552d038a69 204 /******************************************************************************/
Zaitsev 10:41552d038a69 205 /* ARMCC memory allocation wrappers */
Zaitsev 10:41552d038a69 206 /******************************************************************************/
Zaitsev 10:41552d038a69 207
Zaitsev 10:41552d038a69 208 #elif defined(TOOLCHAIN_ARM) // #if defined(TOOLCHAIN_GCC)
Zaitsev 10:41552d038a69 209
Zaitsev 10:41552d038a69 210 /* Enable hooking of memory function only if tracing is also enabled */
Zaitsev 10:41552d038a69 211 #if defined(MBED_MEM_TRACING_ENABLED) || defined(MBED_HEAP_STATS_ENABLED)
Zaitsev 10:41552d038a69 212
Zaitsev 10:41552d038a69 213 extern "C" {
Zaitsev 10:41552d038a69 214 void *$Super$$malloc(size_t size);
Zaitsev 10:41552d038a69 215 void *$Super$$realloc(void *ptr, size_t size);
Zaitsev 10:41552d038a69 216 void *$Super$$calloc(size_t nmemb, size_t size);
Zaitsev 10:41552d038a69 217 void $Super$$free(void *ptr);
Zaitsev 10:41552d038a69 218 }
Zaitsev 10:41552d038a69 219
Zaitsev 10:41552d038a69 220 extern "C" void* $Sub$$malloc(size_t size) {
Zaitsev 10:41552d038a69 221 void *ptr = NULL;
Zaitsev 10:41552d038a69 222 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 223 malloc_stats_mutex->lock();
Zaitsev 10:41552d038a69 224 alloc_info_t *alloc_info = (alloc_info_t*)$Super$$malloc(size + sizeof(alloc_info_t));
Zaitsev 10:41552d038a69 225 if (alloc_info != NULL) {
Zaitsev 10:41552d038a69 226 alloc_info->size = size;
Zaitsev 10:41552d038a69 227 ptr = (void*)(alloc_info + 1);
Zaitsev 10:41552d038a69 228 heap_stats.current_size += size;
Zaitsev 10:41552d038a69 229 heap_stats.total_size += size;
Zaitsev 10:41552d038a69 230 heap_stats.alloc_cnt += 1;
Zaitsev 10:41552d038a69 231 if (heap_stats.current_size > heap_stats.max_size) {
Zaitsev 10:41552d038a69 232 heap_stats.max_size = heap_stats.current_size;
Zaitsev 10:41552d038a69 233 }
Zaitsev 10:41552d038a69 234 } else {
Zaitsev 10:41552d038a69 235 heap_stats.alloc_fail_cnt += 1;
Zaitsev 10:41552d038a69 236 }
Zaitsev 10:41552d038a69 237 malloc_stats_mutex->unlock();
Zaitsev 10:41552d038a69 238 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 239 ptr = $Super$$malloc(size);
Zaitsev 10:41552d038a69 240 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 241 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 242 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 243 mbed_mem_trace_malloc(ptr, size, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 244 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 245 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 246 return ptr;
Zaitsev 10:41552d038a69 247 }
Zaitsev 10:41552d038a69 248
Zaitsev 10:41552d038a69 249 extern "C" void* $Sub$$realloc(void *ptr, size_t size) {
Zaitsev 10:41552d038a69 250 void *new_ptr = NULL;
Zaitsev 10:41552d038a69 251 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 252 // Note - no lock needed since malloc and free are thread safe
Zaitsev 10:41552d038a69 253
Zaitsev 10:41552d038a69 254 // Get old size
Zaitsev 10:41552d038a69 255 uint32_t old_size = 0;
Zaitsev 10:41552d038a69 256 if (ptr != NULL) {
Zaitsev 10:41552d038a69 257 alloc_info_t *alloc_info = ((alloc_info_t*)ptr) - 1;
Zaitsev 10:41552d038a69 258 old_size = alloc_info->size;
Zaitsev 10:41552d038a69 259 }
Zaitsev 10:41552d038a69 260
Zaitsev 10:41552d038a69 261 // Allocate space
Zaitsev 10:41552d038a69 262 if (size != 0) {
Zaitsev 10:41552d038a69 263 new_ptr = malloc(size);
Zaitsev 10:41552d038a69 264 }
Zaitsev 10:41552d038a69 265
Zaitsev 10:41552d038a69 266 // If the new buffer has been allocated copy the data to it
Zaitsev 10:41552d038a69 267 // and free the old buffer
Zaitsev 10:41552d038a69 268 if (new_ptr != NULL) {
Zaitsev 10:41552d038a69 269 uint32_t copy_size = (old_size < size) ? old_size : size;
Zaitsev 10:41552d038a69 270 memcpy(new_ptr, (void*)ptr, copy_size);
Zaitsev 10:41552d038a69 271 free(ptr);
Zaitsev 10:41552d038a69 272 }
Zaitsev 10:41552d038a69 273 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 274 new_ptr = $Super$$realloc(ptr, size);
Zaitsev 10:41552d038a69 275 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 276 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 277 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 278 mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 279 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 280 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 281 return new_ptr;
Zaitsev 10:41552d038a69 282 }
Zaitsev 10:41552d038a69 283
Zaitsev 10:41552d038a69 284 extern "C" void *$Sub$$calloc(size_t nmemb, size_t size) {
Zaitsev 10:41552d038a69 285 void *ptr = NULL;
Zaitsev 10:41552d038a69 286 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 287 // Note - no lock needed since malloc is thread safe
Zaitsev 10:41552d038a69 288 ptr = malloc(nmemb * size);
Zaitsev 10:41552d038a69 289 if (ptr != NULL) {
Zaitsev 10:41552d038a69 290 memset(ptr, 0, nmemb * size);
Zaitsev 10:41552d038a69 291 }
Zaitsev 10:41552d038a69 292 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 293 ptr = $Super$$calloc(nmemb, size);
Zaitsev 10:41552d038a69 294 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 295 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 296 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 297 mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 298 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 299 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 300 return ptr;
Zaitsev 10:41552d038a69 301 }
Zaitsev 10:41552d038a69 302
Zaitsev 10:41552d038a69 303 extern "C" void $Sub$$free(void *ptr) {
Zaitsev 10:41552d038a69 304 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 305 malloc_stats_mutex->lock();
Zaitsev 10:41552d038a69 306 alloc_info_t *alloc_info = NULL;
Zaitsev 10:41552d038a69 307 if (ptr != NULL) {
Zaitsev 10:41552d038a69 308 alloc_info = ((alloc_info_t*)ptr) - 1;
Zaitsev 10:41552d038a69 309 heap_stats.current_size -= alloc_info->size;
Zaitsev 10:41552d038a69 310 heap_stats.alloc_cnt -= 1;
Zaitsev 10:41552d038a69 311 }
Zaitsev 10:41552d038a69 312 $Super$$free((void*)alloc_info);
Zaitsev 10:41552d038a69 313 malloc_stats_mutex->unlock();
Zaitsev 10:41552d038a69 314 #else // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 315 $Super$$free(ptr);
Zaitsev 10:41552d038a69 316 #endif // #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 317 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 318 mem_trace_mutex->lock();
Zaitsev 10:41552d038a69 319 mbed_mem_trace_free(ptr, MBED_CALLER_ADDR());
Zaitsev 10:41552d038a69 320 mem_trace_mutex->unlock();
Zaitsev 10:41552d038a69 321 #endif // #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 322 }
Zaitsev 10:41552d038a69 323
Zaitsev 10:41552d038a69 324 #endif // #if defined(MBED_MEM_TRACING_ENABLED) || defined(MBED_HEAP_STATS_ENABLED)
Zaitsev 10:41552d038a69 325
Zaitsev 10:41552d038a69 326 /******************************************************************************/
Zaitsev 10:41552d038a69 327 /* Allocation wrappers for other toolchains are not supported yet */
Zaitsev 10:41552d038a69 328 /******************************************************************************/
Zaitsev 10:41552d038a69 329
Zaitsev 10:41552d038a69 330 #else // #if defined(TOOLCHAIN_GCC)
Zaitsev 10:41552d038a69 331
Zaitsev 10:41552d038a69 332 #ifdef MBED_MEM_TRACING_ENABLED
Zaitsev 10:41552d038a69 333 #warning Memory tracing is not supported with the current toolchain.
Zaitsev 10:41552d038a69 334 #endif
Zaitsev 10:41552d038a69 335
Zaitsev 10:41552d038a69 336 #ifdef MBED_HEAP_STATS_ENABLED
Zaitsev 10:41552d038a69 337 #warning Heap statistics are not supported with the current toolchain.
Zaitsev 10:41552d038a69 338 #endif
Zaitsev 10:41552d038a69 339
Zaitsev 10:41552d038a69 340 #endif // #if defined(TOOLCHAIN_GCC)
Zaitsev 10:41552d038a69 341