mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

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