ST / ST_Events-old

Dependents:   HelloWorld_CCA01M1 HelloWorld_CCA02M1 CI-data-logger-server HelloWorld_CCA02M1 ... more

This is a fork of the events subdirectory of https://github.com/ARMmbed/mbed-os.

Note, you must import this library with import name: events!!!

Committer:
Martin Kojtal
Date:
Fri Sep 02 11:07:19 2016 +0100
Revision:
7649:2edb2f062201
Parent:
7606:dbabbb13e5b0
Child:
7814:9b2b2d58d7dd
alloc wrappers - fix calloc wrapping for uvisor

Done already in 7c0cc50, same applied to alloc wrappers that was moved
from retarget.

Who changed what in which revision?

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