Biomimetics MBED Library w/ Added Support for CAN3

Dependents:   CAN_TEST SPIne_Plus_DYNO_SENSORS SPIne_Plus_v2 SPIne_Plus_Dyno_v2

Committer:
adimmit
Date:
Tue Mar 09 20:33:24 2021 +0000
Revision:
3:993b4d6ff61e
Parent:
0:083111ae2a11
added CAN3

Who changed what in which revision?

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