Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

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