190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 2f71323e297a928af368937089d3ed71239786f86Andreas Huber * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 4f71323e297a928af368937089d3ed71239786f86Andreas Huber * Use of this source code is governed by a BSD-style license 5f71323e297a928af368937089d3ed71239786f86Andreas Huber * that can be found in the LICENSE file in the root of the source 6f71323e297a928af368937089d3ed71239786f86Andreas Huber * tree. An additional intellectual property rights grant can be found 7f71323e297a928af368937089d3ed71239786f86Andreas Huber * in the file PATENTS. All contributing project authors may 8f71323e297a928af368937089d3ed71239786f86Andreas Huber * be found in the AUTHORS file in the root of the source tree. 990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */ 1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_mem_tracker.c 1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 1590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber jwz 2003-09-30: 1690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Stores a list of addreses, their size, and file and line they came from. 1790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber All exposed lib functions are prefaced by vpx_ and allow the global list 1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber to be thread safe. 1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Current supported platforms are: 2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Linux, Win32, win_ce and vx_works 2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Further support can be added by defining the platform specific mutex 2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber in the memory_tracker struct as well as calls to create/destroy/lock/unlock 2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber the mutex in vpx_memory_tracker_init/Destroy and memory_tracker_lock_mutex/unlock_mutex 2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_config.h" 2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 2790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(__uClinux__) 2890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include <lddk.h> 2990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 3090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 3190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 3290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include <pthread.h> 3390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 3490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define WIN32_LEAN_AND_MEAN 3590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include <windows.h> 3690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include <winbase.h> 3790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include <sem_lib.h> 3990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdio.h> 4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdlib.h> 43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <string.h> // VXWORKS doesn't have a malloc/memory.h file, 44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// this should pull in malloc,free,etc. 4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdarg.h> 4690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 4790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "include/vpx_mem_tracker.h" 4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#undef vpx_malloc // undefine any vpx_mem macros that may affect calls to 50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#undef vpx_free // memory functions in this file 5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#undef vpx_memcpy 5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#undef vpx_memset 5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 5590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifndef USE_GLOBAL_FUNCTION_POINTERS 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# define USE_GLOBAL_FUNCTION_POINTERS 0 // use function pointers instead of compiled functions. 5790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 5890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if USE_GLOBAL_FUNCTION_POINTERS 6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_malloc_func g_malloc = malloc; 6190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_calloc_func g_calloc = calloc; 6290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_realloc_func g_realloc = realloc; 6390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_free_func g_free = free; 6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_memcpy_func g_memcpy = memcpy; 6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_memset_func g_memset = memset; 6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_memmove_func g_memmove = memmove; 6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MALLOC g_malloc 6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_FREE g_free 6990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMCPY g_memcpy 7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMSET g_memset 7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MALLOC vpx_malloc 7390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_FREE vpx_free 7490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMCPY vpx_memcpy 7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMSET vpx_memset 7690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif // USE_GLOBAL_FUNCTION_POINTERS 7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 7890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* prototypes for internal library functions */ 7990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memtrack_log(const char *fmt, ...); 8090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_dump(); 8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_check_integrity(char *file, unsigned int line); 8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_add(size_t addr, unsigned int size, 8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char *file, unsigned int line, 8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int padded); 8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_remove(size_t addr); 8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic struct mem_block *memory_tracker_find(size_t addr); 8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(NO_MUTEX) 8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define memory_tracker_lock_mutex() (!g_b_mem_tracker_inited) 9090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define memory_tracker_unlock_mutex() 9190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 9290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_lock_mutex(); 9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_unlock_mutex(); 9490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 9590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 9690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifndef VPX_NO_GLOBALS 97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct memory_tracker { 98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *head, 99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * tail; 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int len, 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang totalsize; 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int current_allocated, 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang max_allocated; 10490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pthread_mutex_t mutex; 10790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang HANDLE mutex; 10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang SEM_ID mutex; 11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NO_MUTEX) 11290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 11390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#error "No mutex type defined for this platform!" 11490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 11590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int padding_size, 117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pad_value; 11890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}; 11990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic struct memory_tracker memtrack; // our global memory allocation list 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int g_b_mem_tracker_inited = 0; // indicates whether the global list has 122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// been initialized (1:yes/0:no) 123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic struct { 124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FILE *file; 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int type; 126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void (*func)(void *userdata, const char *fmt, va_list args); 127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void *userdata; 12890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} g_logging = {NULL, 0, NULL, NULL}; 12990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 13090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include "vpx_global_handling.h" 13190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define g_b_mem_tracker_inited vpxglobalm(vpxmem,g_b_mem_tracker_inited) 13290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define g_logging vpxglobalm(vpxmem,g_logging) 13390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define memtrack vpxglobalm(vpxmem,memtrack) 13490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif // #ifndef VPX_NO_GLOBALS 13590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 13690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void *vpx_malloc(size_t size); 13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void vpx_free(void *memblk); 13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void *vpx_memcpy(void *dest, const void *src, size_t length); 13990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void *vpx_memset(void *dest, int val, size_t length); 14090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 14190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 14390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * Exposed library functions 14490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 14590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 14690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 14790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_init(int padding_size, int pad_value) 14990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber padding_size - the size of the padding before and after each mem addr. 15090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Values > 0 indicate that integrity checks can be performed 15190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber by inspecting these areas. 15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber pad_value - the initial value within the padding area before and after 15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber each mem addr. 15490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 15590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Initializes global memory tracker structure 15690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Allocates the head of the list 15790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vpx_memory_tracker_init(int padding_size, int pad_value) { 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!g_b_mem_tracker_inited) { 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ((memtrack.head = (struct mem_block *) 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang MEM_TRACK_MALLOC(sizeof(struct mem_block)))) { 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ret; 16390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang MEM_TRACK_MEMSET(memtrack.head, 0, sizeof(struct mem_block)); 16590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.tail = memtrack.head; 16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.current_allocated = 0; 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.max_allocated = 0; 17090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.padding_size = padding_size; 172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.pad_value = pad_value; 17390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 17490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = pthread_mutex_init(&memtrack.mutex, 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang NULL); /*mutex attributes (NULL=default)*/ 17790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.mutex = CreateMutex(NULL, /*security attributes*/ 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FALSE, /*we don't want initial ownership*/ 180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang NULL); /*mutex name*/ 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = !memtrack.mutex; 18290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.mutex = sem_bcreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority based mutex*/ 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang SEM_FULL); /*SEM_FULL initial state is unlocked*/ 185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = !memtrack.mutex; 18690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NO_MUTEX) 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = 0; 18890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 18990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ret) { 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("vpx_memory_tracker_init: Error creating mutex!\n"); 192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang MEM_TRACK_FREE(memtrack.head); 194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.head = NULL; 195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("Memory Tracker init'd, v."vpx_mem_tracker_version" pad_size:%d pad_val:0x%x %d\n" 197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, padding_size 198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, pad_value 199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, pad_value); 200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_b_mem_tracker_inited = 1; 201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 20290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 20490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return g_b_mem_tracker_inited; 20690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 20790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 20890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 20990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_destroy() 21090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If our global struct was initialized zeros out all its members, 21190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber frees memory and destroys it's mutex 21290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vpx_memory_tracker_destroy() { 214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!memory_tracker_lock_mutex()) { 215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *p = memtrack.head, 216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * p2 = memtrack.head; 21790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_dump(); 21990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (p) { 221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p2 = p; 222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p = p->next; 22390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang MEM_TRACK_FREE(p2); 225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 22690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.head = NULL; 228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.tail = NULL; 229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.len = 0; 230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.current_allocated = 0; 231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.max_allocated = 0; 23290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!g_logging.type && g_logging.file && g_logging.file != stderr) { 234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fclose(g_logging.file); 235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.file = NULL; 236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 23790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_unlock_mutex(); 23990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_b_mem_tracker_inited = 0; 241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 24290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 24390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 24490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 24590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_add(size_t addr, unsigned int size, 24690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char * file, unsigned int line) 24790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr - memory address to be added to list 24890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber size - size of addr 24990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber file - the file addr was referenced from 25090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber line - the line in file addr was referenced from 25190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Adds memory address addr, it's size, file and line it came from 25290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber to the global list via the thread safe internal library function 25390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 25490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vpx_memory_tracker_add(size_t addr, unsigned int size, 25590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char *file, unsigned int line, 256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int padded) { 257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_add(addr, size, file, line, padded); 25890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 25990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 26090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 26190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_remove(size_t addr) 26290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr - memory address to be removed from list 26390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Removes addr from the global list via the thread safe 26490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber internal remove function 26590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 26690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Same as described for memory_tracker_remove 26790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vpx_memory_tracker_remove(size_t addr) { 269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return memory_tracker_remove(addr); 27090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 27190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 27290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 27390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_find(size_t addr) 27490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr - address to be found in list 27590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 27690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If found, pointer to the memory block that matches addr 27790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber NULL otherwise 27890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct mem_block *vpx_memory_tracker_find(size_t addr) { 280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *p = NULL; 28190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!memory_tracker_lock_mutex()) { 283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p = memory_tracker_find(addr); 284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_unlock_mutex(); 285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return p; 28890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 28990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 29090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 29190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_dump() 29290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Locks the memory tracker's mutex and calls the internal 29390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber library function to dump the current contents of the 29490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber global memory allocation list 29590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vpx_memory_tracker_dump() { 297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!memory_tracker_lock_mutex()) { 298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_dump(); 299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_unlock_mutex(); 300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 30190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 30290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 30390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 30490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_check_integrity(char* file, unsigned int line) 30590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber file - The file name where the check was placed 30690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber line - The line in file where the check was placed 30790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Locks the memory tracker's mutex and calls the internal 30890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber integrity check function to inspect every address in the global 30990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory allocation list 31090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vpx_memory_tracker_check_integrity(char *file, unsigned int line) { 312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!memory_tracker_lock_mutex()) { 313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_check_integrity(file, line); 314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_unlock_mutex(); 315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 31690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 31790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 31890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 31990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_set_log_type 32090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Sets the logging type for the memory tracker. Based on the value it will 32190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber direct its output to the appropriate place. 32290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 32390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 32490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the logging type could not be set, because the value was invalid 32590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber or because a file could not be opened 32690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vpx_memory_tracker_set_log_type(int type, char *option) { 328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ret = -1; 32990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang switch (type) { 33190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case 0: 332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.type = 0; 33390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!option) { 335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.file = stderr; 336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = 0; 337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ((g_logging.file = fopen((char *)option, "w"))) 339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = 0; 340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 34190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 34390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(WIN32) && !defined(_WIN32_WCE) 34490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case 1: 345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.type = type; 346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = 0; 347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 34890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 34990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber default: 350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 35290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // output the version to the new logging destination 354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!ret) 355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("Memory Tracker logging initialized, " 356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "Memory Tracker v."vpx_mem_tracker_version"\n"); 35790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ret; 35990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 36090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 36190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 36290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_set_log_func 36390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Sets a logging function to be used by the memory tracker. 36490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 36590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 36690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the logging type could not be set because logfunc was NULL 36790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 36890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint vpx_memory_tracker_set_log_func(void *userdata, 36990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber void(*logfunc)(void *userdata, 370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const char *fmt, va_list args)) { 371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ret = -1; 372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (logfunc) { 374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.type = -1; 375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.userdata = userdata; 376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.func = logfunc; 377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = 0; 378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // output the version to the new logging destination 381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!ret) 382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("Memory Tracker logging initialized, " 383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "Memory Tracker v."vpx_mem_tracker_version"\n"); 384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ret; 38690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 38790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 38890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 38990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 39090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * END - Exposed library functions 39190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 39290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 39390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 39490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 39590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 39690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 39790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * Internal library functions 39890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 39990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 40090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void memtrack_log(const char *fmt, ...) { 402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang va_list list; 40390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang va_start(list, fmt); 40590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang switch (g_logging.type) { 40790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case -1: 40890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_logging.func) 410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_logging.func(g_logging.userdata, fmt, list); 41190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 41390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case 0: 41490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_logging.file) { 416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vfprintf(g_logging.file, fmt, list); 417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fflush(g_logging.file); 418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 41990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 42190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(WIN32) && !defined(_WIN32_WCE) 422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case 1: { 423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang char temp[1024]; 424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _vsnprintf(temp, sizeof(temp) / sizeof(char) - 1, fmt, list); 425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang OutputDebugString(temp); 42690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 42790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 42890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 42990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber default: 430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 43290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang va_end(list); 43490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 43590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 43690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 43790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_dump() 43890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Dumps the current contents of the global memory allocation list 43990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void memory_tracker_dump() { 441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int i = 0; 442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *p = (memtrack.head ? memtrack.head->next : NULL); 44390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("\n_currently Allocated= %d; Max allocated= %d\n", 445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.current_allocated, memtrack.max_allocated); 44690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (p) { 44890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(WIN32) && !defined(_WIN32_WCE) 44990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /*when using outputdebugstring, output filenames so they 451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang can be clicked to be opened in visual studio*/ 452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_logging.type == 1) 453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file:\n" 454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang " %s(%d):\n", i, 455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->addr, i, p->size, 456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->file, p->line); 457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else 45890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file: %s, line: %d\n", i, 460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->addr, i, p->size, 461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->file, p->line); 46290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p = p->next; 464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ++i; 465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 46690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("\n"); 46890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 46990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 47090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 47190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_check_integrity(char* file, unsigned int file) 47290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber file - the file name where the check was placed 47390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber line - the line in file where the check was placed 47490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If a padding_size was supplied to vpx_memory_tracker_init() 47590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber this function will check ea. addr in the list verifying that 47690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr-padding_size and addr+padding_size is filled with pad_value 47790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void memory_tracker_check_integrity(char *file, unsigned int line) { 479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (memtrack.padding_size) { 480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int i, 481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang index = 0; 482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *p_show_me, 483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * p_show_me2; 484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int tempme = memtrack.pad_value, 485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dead1, 486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dead2; 487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *x_bounds; 488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *p = memtrack.head->next; 489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (p) { 491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // x_bounds = (unsigned char*)p->addr; 492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // back up VPX_BYTE_ALIGNMENT 493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // x_bounds -= memtrack.padding_size; 494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (p->padded) { // can the bounds be checked? 496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /*yes, move to the address that was actually allocated 497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang by the vpx_* calls*/ 498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang x_bounds = (unsigned char *)(((size_t *)p->addr)[-1]); 499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < memtrack.padding_size; i += sizeof(unsigned int)) { 501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p_show_me = (x_bounds + i); 502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p_show_me2 = (unsigned char *)(p->addr + p->size + i); 503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang MEM_TRACK_MEMCPY(&dead1, p_show_me, sizeof(unsigned int)); 505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang MEM_TRACK_MEMCPY(&dead2, p_show_me2, sizeof(unsigned int)); 506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ((dead1 != tempme) || (dead2 != tempme)) { 508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("\n[vpx_mem integrity check failed]:\n" 509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang " index[%d,%d] {%s:%d} addr=0x%x, size=%d," 510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang " file: %s, line: %d c0:0x%x c1:0x%x\n", 511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang index, i, file, line, p->addr, p->size, p->file, 512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->line, dead1, dead2); 513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 51490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ++index; 518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p = p->next; 51990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 52190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 52290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 52390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 52490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_add(size_t addr, unsigned int size, 52590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char * file, unsigned int line) 52690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Adds an address (addr), it's size, file and line number to our list. 52790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Adjusts the total bytes allocated and max bytes allocated if necessary. 52890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If memory cannot be allocated the list will be destroyed. 52990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 53090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid memory_tracker_add(size_t addr, unsigned int size, 53190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char *file, unsigned int line, 532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int padded) { 533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!memory_tracker_lock_mutex()) { 534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *p; 53590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p = MEM_TRACK_MALLOC(sizeof(struct mem_block)); 53790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (p) { 539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->prev = memtrack.tail; 540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->prev->next = p; 541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->addr = addr; 542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->size = size; 543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->line = line; 544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->file = file; 545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->padded = padded; 546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->next = NULL; 54790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.tail = p; 54990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.current_allocated += size; 55190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (memtrack.current_allocated > memtrack.max_allocated) 553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.max_allocated = memtrack.current_allocated; 55490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // memtrack_log("memory_tracker_add: added addr=0x%.8x\n", addr); 55690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_unlock_mutex(); 558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("memory_tracker_add: error allocating memory!\n"); 560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_unlock_mutex(); 561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memory_tracker_destroy(); 56290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 56490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 56590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 56690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 56790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_remove(size_t addr) 56890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Removes an address and its corresponding size (if they exist) 56990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber from the memory tracker list and adjusts the current number 57090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber of bytes allocated. 57190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 57290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 57390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the mutex could not be locked 57490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -2: if the addr was not found in the list 57590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint memory_tracker_remove(size_t addr) { 577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ret = -1; 57890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!memory_tracker_lock_mutex()) { 580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *p; 58190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ((p = memory_tracker_find(addr))) { 583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.current_allocated -= p->size; 58490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->prev->next = p->next; 58690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (p->next) 588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p->next->prev = p->prev; 589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else 590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack.tail = p->prev; 59190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = 0; 593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang MEM_TRACK_FREE(p); 594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (addr) 596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("memory_tracker_remove(): addr not found in list," 597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang " 0x%.8x\n", addr); 59890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = -2; 60090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 60190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memory_tracker_unlock_mutex(); 603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ret; 60690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 60790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 60890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 60990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_find(size_t addr) 61090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Finds an address in our addrs list 61190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber NOTE: the mutex MUST be locked in the other internal 61290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber functions before calling this one. This avoids 61390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber the need for repeated locking and unlocking as in Remove 61490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Returns: pointer to the mem block if found, NULL otherwise 61590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic struct mem_block *memory_tracker_find(size_t addr) { 617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct mem_block *p = NULL; 61890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (memtrack.head) { 620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p = memtrack.head->next; 62190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (p && (p->addr != addr)) 623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang p = p->next; 624ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 62590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return p; 62790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 62890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 62990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 63090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if !defined(NO_MUTEX) 63190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 63290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_lock_mutex() 63390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Locks the memory tracker mutex with a platform specific call 63490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Returns: 63590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: Success 63690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber <0: Failure, either the mutex was not initialized 63790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber or the call to lock the mutex failed 63890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int memory_tracker_lock_mutex() { 640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ret = -1; 64190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_b_mem_tracker_inited) { 64390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 64490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = pthread_mutex_lock(&memtrack.mutex); 64690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = WaitForSingleObject(memtrack.mutex, INFINITE); 64890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = sem_take(memtrack.mutex, WAIT_FOREVER); 65090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 65190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ret) { 653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("memory_tracker_lock_mutex: mutex lock failed\n"); 65490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 65690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ret; 65890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 65990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 66090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 66190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex() 66290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Unlocks the memory tracker mutex with a platform specific call 66390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Returns: 66490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: Success 66590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber <0: Failure, either the mutex was not initialized 66690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber or the call to unlock the mutex failed 66790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int memory_tracker_unlock_mutex() { 669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ret = -1; 67090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_b_mem_tracker_inited) { 67290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 67390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = pthread_mutex_unlock(&memtrack.mutex); 67590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = !ReleaseMutex(memtrack.mutex); 67790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ret = sem_give(memtrack.mutex); 67990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 68090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ret) { 682ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memtrack_log("memory_tracker_unlock_mutex: mutex unlock failed\n"); 68390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 68590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ret; 68790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 68890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 68990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 69090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 69190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_set_functions 69290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 69390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Sets the function pointers for the standard library functions. 69490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 69590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 69690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 69790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the use global function pointers is not set. 69890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 69990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l 700ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, mem_track_calloc_func g_calloc_l 701ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, mem_track_realloc_func g_realloc_l 702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, mem_track_free_func g_free_l 703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, mem_track_memcpy_func g_memcpy_l 704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, mem_track_memset_func g_memset_l 705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang, mem_track_memmove_func g_memmove_l) { 70690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if USE_GLOBAL_FUNCTION_POINTERS 70790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_malloc_l) 709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_malloc = g_malloc_l; 71090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_calloc_l) 712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_calloc = g_calloc_l; 71390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_realloc_l) 715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_realloc = g_realloc_l; 71690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_free_l) 718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_free = g_free_l; 71990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_memcpy_l) 721ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_memcpy = g_memcpy_l; 72290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 723ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_memset_l) 724ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_memset = g_memset_l; 72590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (g_memmove_l) 727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang g_memmove = g_memmove_l; 72890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 73090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)g_malloc_l; 732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)g_calloc_l; 733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)g_realloc_l; 734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)g_free_l; 735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)g_memcpy_l; 736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)g_memset_l; 737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)g_memmove_l; 738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -1; 73990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 74090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 741