mbed library sources. Supersedes mbed-src.

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_mem_trace.cpp Source File

mbed_mem_trace.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2016 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include <stdlib.h>
00019 #include <stdarg.h>
00020 #include <stdio.h>
00021 #include "platform/mbed_mem_trace.h"
00022 #include "platform/mbed_critical.h"
00023 #include "platform/SingletonPtr.h"
00024 #include "platform/PlatformMutex.h"
00025 
00026 /******************************************************************************
00027  * Internal variables, functions and helpers
00028  *****************************************************************************/
00029 
00030 /* The callback function that will be called after a traced memory operations finishes. */
00031 static mbed_mem_trace_cb_t mem_trace_cb;
00032 static mbed_mem_trace_cb_t mem_trace_cb_reserve;
00033 /* 'trace_lock_count' guards "trace inside trace" situations (for example, the implementation
00034  * of realloc() might call malloc() internally, and since malloc() is also traced, this could
00035  * result in two calls to the callback function instead of one. */
00036 static uint8_t trace_lock_count;
00037 static SingletonPtr<PlatformMutex>  mem_trace_mutex;
00038 
00039 #define TRACE_FIRST_LOCK() (trace_lock_count < 2)
00040 
00041 
00042 /******************************************************************************
00043  * Public interface
00044  *****************************************************************************/
00045 
00046 void mbed_mem_trace_set_callback(mbed_mem_trace_cb_t cb)
00047 {
00048     mem_trace_cb = cb;
00049 }
00050 
00051 void mbed_mem_trace_disable()
00052 {
00053     mbed_mem_trace_lock();
00054     if (mem_trace_cb) {
00055         mem_trace_cb_reserve = mem_trace_cb;
00056         mem_trace_cb = 0;
00057     }
00058     mbed_mem_trace_unlock();
00059 }
00060 void mbed_mem_trace_enable()
00061 {
00062     mbed_mem_trace_lock();
00063     if (!mem_trace_cb && mem_trace_cb_reserve) {
00064         mem_trace_cb = mem_trace_cb_reserve;
00065     }
00066     mbed_mem_trace_unlock();
00067 }
00068 
00069 void mbed_mem_trace_lock()
00070 {
00071     mem_trace_mutex->lock();
00072     trace_lock_count++;
00073 }
00074 
00075 void mbed_mem_trace_unlock()
00076 {
00077     trace_lock_count--;
00078     mem_trace_mutex->unlock();
00079 }
00080 
00081 void *mbed_mem_trace_malloc(void *res, size_t size, void *caller)
00082 {
00083     if (mem_trace_cb) {
00084         if (TRACE_FIRST_LOCK()) {
00085             mem_trace_cb(MBED_MEM_TRACE_MALLOC, res, caller, size);
00086         }
00087     }
00088     return res;
00089 }
00090 
00091 void *mbed_mem_trace_realloc(void *res, void *ptr, size_t size, void *caller)
00092 {
00093     if (mem_trace_cb) {
00094         if (TRACE_FIRST_LOCK()) {
00095             mem_trace_cb(MBED_MEM_TRACE_REALLOC, res, caller, ptr, size);
00096         }
00097     }
00098     return res;
00099 }
00100 
00101 void *mbed_mem_trace_calloc(void *res, size_t num, size_t size, void *caller)
00102 {
00103     if (mem_trace_cb) {
00104         if (TRACE_FIRST_LOCK()) {
00105             mem_trace_cb(MBED_MEM_TRACE_CALLOC, res, caller, num, size);
00106         }
00107     }
00108     return res;
00109 }
00110 
00111 void mbed_mem_trace_free(void *ptr, void *caller)
00112 {
00113     if (mem_trace_cb) {
00114         if (TRACE_FIRST_LOCK()) {
00115             mem_trace_cb(MBED_MEM_TRACE_FREE, NULL, caller, ptr);
00116         }
00117     }
00118 }
00119 
00120 void mbed_mem_trace_default_callback(uint8_t op, void *res, void *caller, ...)
00121 {
00122     va_list va;
00123     size_t temp_s1, temp_s2;
00124     void *temp_ptr;
00125 
00126     va_start(va, caller);
00127     switch (op) {
00128         case MBED_MEM_TRACE_MALLOC:
00129             temp_s1 = va_arg(va, size_t);
00130             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "m:%p;%p-%u\n", res, caller, temp_s1);
00131             break;
00132 
00133         case MBED_MEM_TRACE_REALLOC:
00134             temp_ptr = va_arg(va, void *);
00135             temp_s1 = va_arg(va, size_t);
00136             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "r:%p;%p-%p;%u\n", res, caller, temp_ptr, temp_s1);
00137             break;
00138 
00139         case MBED_MEM_TRACE_CALLOC:
00140             temp_s1 = va_arg(va, size_t);
00141             temp_s2 = va_arg(va, size_t);
00142             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "c:%p;%p-%u;%u\n", res, caller, temp_s1, temp_s2);
00143             break;
00144 
00145         case MBED_MEM_TRACE_FREE:
00146             temp_ptr = va_arg(va, void *);
00147             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "f:%p;%p-%p\n", res, caller, temp_ptr);
00148             break;
00149 
00150         default:
00151             printf("?\n");
00152     }
00153     va_end(va);
00154 }
00155