Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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-2019 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/SingletonPtr.h"
00023 #include "platform/PlatformMutex.h"
00024 
00025 /******************************************************************************
00026  * Internal variables, functions and helpers
00027  *****************************************************************************/
00028 
00029 /* The callback function that will be called after a traced memory operations finishes. */
00030 static mbed_mem_trace_cb_t mem_trace_cb;
00031 static mbed_mem_trace_cb_t mem_trace_cb_reserve;
00032 /* 'trace_lock_count' guards "trace inside trace" situations (for example, the implementation
00033  * of realloc() might call malloc() internally, and since malloc() is also traced, this could
00034  * result in two calls to the callback function instead of one. */
00035 static uint8_t trace_lock_count;
00036 static SingletonPtr<PlatformMutex>  mem_trace_mutex;
00037 
00038 #define TRACE_FIRST_LOCK() (trace_lock_count < 2)
00039 
00040 
00041 /******************************************************************************
00042  * Public interface
00043  *****************************************************************************/
00044 
00045 void mbed_mem_trace_set_callback(mbed_mem_trace_cb_t cb)
00046 {
00047     mem_trace_cb = cb;
00048 }
00049 
00050 void mbed_mem_trace_disable()
00051 {
00052     mbed_mem_trace_lock();
00053     if (mem_trace_cb) {
00054         mem_trace_cb_reserve = mem_trace_cb;
00055         mem_trace_cb = 0;
00056     }
00057     mbed_mem_trace_unlock();
00058 }
00059 void mbed_mem_trace_enable()
00060 {
00061     mbed_mem_trace_lock();
00062     if (!mem_trace_cb && mem_trace_cb_reserve) {
00063         mem_trace_cb = mem_trace_cb_reserve;
00064     }
00065     mbed_mem_trace_unlock();
00066 }
00067 
00068 void mbed_mem_trace_lock()
00069 {
00070     mem_trace_mutex->lock();
00071     trace_lock_count++;
00072 }
00073 
00074 void mbed_mem_trace_unlock()
00075 {
00076     trace_lock_count--;
00077     mem_trace_mutex->unlock();
00078 }
00079 
00080 void *mbed_mem_trace_malloc(void *res, size_t size, void *caller)
00081 {
00082     if (mem_trace_cb) {
00083         if (TRACE_FIRST_LOCK()) {
00084             mem_trace_cb(MBED_MEM_TRACE_MALLOC, res, caller, size);
00085         }
00086     }
00087     return res;
00088 }
00089 
00090 void *mbed_mem_trace_realloc(void *res, void *ptr, size_t size, void *caller)
00091 {
00092     if (mem_trace_cb) {
00093         if (TRACE_FIRST_LOCK()) {
00094             mem_trace_cb(MBED_MEM_TRACE_REALLOC, res, caller, ptr, size);
00095         }
00096     }
00097     return res;
00098 }
00099 
00100 void *mbed_mem_trace_calloc(void *res, size_t num, size_t size, void *caller)
00101 {
00102     if (mem_trace_cb) {
00103         if (TRACE_FIRST_LOCK()) {
00104             mem_trace_cb(MBED_MEM_TRACE_CALLOC, res, caller, num, size);
00105         }
00106     }
00107     return res;
00108 }
00109 
00110 void mbed_mem_trace_free(void *ptr, void *caller)
00111 {
00112     if (mem_trace_cb) {
00113         if (TRACE_FIRST_LOCK()) {
00114             mem_trace_cb(MBED_MEM_TRACE_FREE, NULL, caller, ptr);
00115         }
00116     }
00117 }
00118 
00119 void mbed_mem_trace_default_callback(uint8_t op, void *res, void *caller, ...)
00120 {
00121     va_list va;
00122     size_t temp_s1, temp_s2;
00123     void *temp_ptr;
00124 
00125     va_start(va, caller);
00126     switch (op) {
00127         case MBED_MEM_TRACE_MALLOC:
00128             temp_s1 = va_arg(va, size_t);
00129             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "m:%p;%p-%u\n", res, caller, temp_s1);
00130             break;
00131 
00132         case MBED_MEM_TRACE_REALLOC:
00133             temp_ptr = va_arg(va, void *);
00134             temp_s1 = va_arg(va, size_t);
00135             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "r:%p;%p-%p;%u\n", res, caller, temp_ptr, temp_s1);
00136             break;
00137 
00138         case MBED_MEM_TRACE_CALLOC:
00139             temp_s1 = va_arg(va, size_t);
00140             temp_s2 = va_arg(va, size_t);
00141             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "c:%p;%p-%u;%u\n", res, caller, temp_s1, temp_s2);
00142             break;
00143 
00144         case MBED_MEM_TRACE_FREE:
00145             temp_ptr = va_arg(va, void *);
00146             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "f:%p;%p-%p\n", res, caller, temp_ptr);
00147             break;
00148 
00149         default:
00150             printf("?\n");
00151     }
00152     va_end(va);
00153 }