Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

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