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*/ 2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_ports/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#elif defined(NDS_NITRO) 4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include <nitro.h> 4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include <nitro/os.h> 4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 4390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 4490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdio.h> 4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdlib.h> 4690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <string.h> //VXWORKS doesn't have a malloc/memory.h file, 4790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//this should pull in malloc,free,etc. 4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdarg.h> 4990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "include/vpx_mem_tracker.h" 5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#undef vpx_malloc //undefine any vpx_mem macros that may affect calls to 5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#undef vpx_free //memory functions in this file 5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#undef vpx_memcpy 5590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#undef vpx_memset 5690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 5790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 5890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifndef USE_GLOBAL_FUNCTION_POINTERS 5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define USE_GLOBAL_FUNCTION_POINTERS 0 //use function pointers instead of compiled functions. 6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 6190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 6290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if USE_GLOBAL_FUNCTION_POINTERS 6390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_malloc_func g_malloc = malloc; 6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_calloc_func g_calloc = calloc; 6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_realloc_func g_realloc = realloc; 6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_free_func g_free = free; 6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_memcpy_func g_memcpy = memcpy; 6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_memset_func g_memset = memset; 6990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic mem_track_memmove_func g_memmove = memmove; 7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MALLOC g_malloc 7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_FREE g_free 7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMCPY g_memcpy 7390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMSET g_memset 7490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MALLOC vpx_malloc 7690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_FREE vpx_free 7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMCPY vpx_memcpy 7890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define MEM_TRACK_MEMSET vpx_memset 7990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif // USE_GLOBAL_FUNCTION_POINTERS 8090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* prototypes for internal library functions */ 8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memtrack_log(const char *fmt, ...); 8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_dump(); 8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_check_integrity(char *file, unsigned int line); 8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_add(size_t addr, unsigned int size, 8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char *file, unsigned int line, 8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int padded); 8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_remove(size_t addr); 8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic struct mem_block *memory_tracker_find(size_t addr); 9090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 9190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(NO_MUTEX) 9290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define memory_tracker_lock_mutex() (!g_b_mem_tracker_inited) 9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# define memory_tracker_unlock_mutex() 9490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 9590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_lock_mutex(); 9690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_unlock_mutex(); 9790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 9890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 9990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifndef VPX_NO_GLOBALS 10090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstruct memory_tracker 10190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 10290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *head, 10390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * tail; 10490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int len, 10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber totalsize; 10690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber unsigned int current_allocated, 10790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber max_allocated; 10890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 11090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber pthread_mutex_t mutex; 11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 11290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber HANDLE mutex; 11390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 11490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber SEM_ID mutex; 11590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NDS_NITRO) 11690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber OSMutex mutex; 11790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NO_MUTEX) 11890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 11990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#error "No mutex type defined for this platform!" 12090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 12190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 12290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int padding_size, 12390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber pad_value; 12490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}; 12590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 12690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic struct memory_tracker memtrack; //our global memory allocation list 12790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int g_b_mem_tracker_inited = 0; //indicates whether the global list has 12890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//been initialized (1:yes/0:no) 12990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic struct 13090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 13190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber FILE *file; 13290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int type; 13390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber void (*func)(void *userdata, const char *fmt, va_list args); 13490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber void *userdata; 13590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} g_logging = {NULL, 0, NULL, NULL}; 13690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include "vpx_global_handling.h" 13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define g_b_mem_tracker_inited vpxglobalm(vpxmem,g_b_mem_tracker_inited) 13990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define g_logging vpxglobalm(vpxmem,g_logging) 14090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define memtrack vpxglobalm(vpxmem,memtrack) 14190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif // #ifndef VPX_NO_GLOBALS 14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 14390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void *vpx_malloc(size_t size); 14490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void vpx_free(void *memblk); 14590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void *vpx_memcpy(void *dest, const void *src, size_t length); 14690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void *vpx_memset(void *dest, int val, size_t length); 14790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 14990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 15090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * Exposed library functions 15190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 15490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 15590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_init(int padding_size, int pad_value) 15690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber padding_size - the size of the padding before and after each mem addr. 15790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Values > 0 indicate that integrity checks can be performed 15890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber by inspecting these areas. 15990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber pad_value - the initial value within the padding area before and after 16090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber each mem addr. 16190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 16290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Initializes global memory tracker structure 16390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Allocates the head of the list 16490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 16590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint vpx_memory_tracker_init(int padding_size, int pad_value) 16690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!g_b_mem_tracker_inited) 16890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 16990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if ((memtrack.head = (struct mem_block *) 17090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber MEM_TRACK_MALLOC(sizeof(struct mem_block)))) 17190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 17290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int ret; 17390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 17490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber MEM_TRACK_MEMSET(memtrack.head, 0, sizeof(struct mem_block)); 17590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 17690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.tail = memtrack.head; 17790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 17890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.current_allocated = 0; 17990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.max_allocated = 0; 18090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 18190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.padding_size = padding_size; 18290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.pad_value = pad_value; 18390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 18490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 18590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = pthread_mutex_init(&memtrack.mutex, 18690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber NULL); /*mutex attributes (NULL=default)*/ 18790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 18890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.mutex = CreateMutex(NULL, /*security attributes*/ 18990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber FALSE, /*we don't want initial ownership*/ 19090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber NULL); /*mutex name*/ 19190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = !memtrack.mutex; 19290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 19390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.mutex = sem_bcreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority based mutex*/ 19490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber SEM_FULL); /*SEM_FULL initial state is unlocked*/ 19590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = !memtrack.mutex; 19690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NDS_NITRO) 19790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber os_init_mutex(&memtrack.mutex); 19890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 19990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NO_MUTEX) 20090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 20190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 20290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 20390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (ret) 20490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 20590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("vpx_memory_tracker_init: Error creating mutex!\n"); 20690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 20790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber MEM_TRACK_FREE(memtrack.head); 20890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.head = NULL; 20990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 21090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber else 21190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 21290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("Memory Tracker init'd, v."vpx_mem_tracker_version" pad_size:%d pad_val:0x%x %d\n" 21390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , padding_size 21490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , pad_value 21590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , pad_value); 21690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_b_mem_tracker_inited = 1; 21790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 21890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 21990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 22090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 22190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return g_b_mem_tracker_inited; 22290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 22390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 22490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 22590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_destroy() 22690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If our global struct was initialized zeros out all its members, 22790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber frees memory and destroys it's mutex 22890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 22990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vpx_memory_tracker_destroy() 23090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 23190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!memory_tracker_lock_mutex()) 23290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 23390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *p = memtrack.head, 23490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * p2 = memtrack.head; 23590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 23690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_dump(); 23790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 23890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber while (p) 23990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 24090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p2 = p; 24190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p = p->next; 24290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 24390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber MEM_TRACK_FREE(p2); 24490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 24590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 24690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.head = NULL; 24790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.tail = NULL; 24890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.len = 0; 24990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.current_allocated = 0; 25090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.max_allocated = 0; 25190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 25290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!g_logging.type && g_logging.file && g_logging.file != stderr) 25390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 25490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if !defined(NDS_NITRO) 25590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber fclose(g_logging.file); 25690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 25790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.file = NULL; 25890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 25990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 26090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex(); 26190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 26290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_b_mem_tracker_inited = 0; 26390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 26490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 26590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 26690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 26790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_add(size_t addr, unsigned int size, 26890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char * file, unsigned int line) 26990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr - memory address to be added to list 27090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber size - size of addr 27190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber file - the file addr was referenced from 27290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber line - the line in file addr was referenced from 27390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Adds memory address addr, it's size, file and line it came from 27490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber to the global list via the thread safe internal library function 27590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 27690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vpx_memory_tracker_add(size_t addr, unsigned int size, 27790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char *file, unsigned int line, 27890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int padded) 27990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 28090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_add(addr, size, file, line, padded); 28190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 28290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 28390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 28490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_remove(size_t addr) 28590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr - memory address to be removed from list 28690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Removes addr from the global list via the thread safe 28790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber internal remove function 28890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 28990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Same as described for memory_tracker_remove 29090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 29190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint vpx_memory_tracker_remove(size_t addr) 29290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 29390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return memory_tracker_remove(addr); 29490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 29590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 29690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 29790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_find(size_t addr) 29890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr - address to be found in list 29990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 30090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If found, pointer to the memory block that matches addr 30190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber NULL otherwise 30290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 30390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstruct mem_block *vpx_memory_tracker_find(size_t addr) 30490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 30590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *p = NULL; 30690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 30790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!memory_tracker_lock_mutex()) 30890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 30990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p = memory_tracker_find(addr); 31090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex(); 31190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 31290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 31390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return p; 31490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 31590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 31690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 31790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_dump() 31890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Locks the memory tracker's mutex and calls the internal 31990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber library function to dump the current contents of the 32090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber global memory allocation list 32190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 32290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vpx_memory_tracker_dump() 32390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 32490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!memory_tracker_lock_mutex()) 32590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 32690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_dump(); 32790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex(); 32890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 32990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 33090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 33190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 33290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_check_integrity(char* file, unsigned int line) 33390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber file - The file name where the check was placed 33490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber line - The line in file where the check was placed 33590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Locks the memory tracker's mutex and calls the internal 33690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber integrity check function to inspect every address in the global 33790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory allocation list 33890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 33990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vpx_memory_tracker_check_integrity(char *file, unsigned int line) 34090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 34190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!memory_tracker_lock_mutex()) 34290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 34390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_check_integrity(file, line); 34490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex(); 34590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 34690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 34790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 34890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 34990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_set_log_type 35090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Sets the logging type for the memory tracker. Based on the value it will 35190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber direct its output to the appropriate place. 35290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 35390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 35490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the logging type could not be set, because the value was invalid 35590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber or because a file could not be opened 35690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 35790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint vpx_memory_tracker_set_log_type(int type, char *option) 35890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 35990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int ret = -1; 36090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 36190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber switch (type) 36290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 36390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case 0: 36490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.type = 0; 36590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 36690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!option) 36790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 36890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.file = stderr; 36990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 37090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 37190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 37290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if !defined(NDS_NITRO) 37390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber else 37490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 37590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if ((g_logging.file = fopen((char *)option, "w"))) 37690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 37790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 37890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 37990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 38090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 38190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(WIN32) && !defined(_WIN32_WCE) 38290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case 1: 38390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.type = type; 38490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 38590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 38690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 38790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber default: 38890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 38990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 39090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 39190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber //output the version to the new logging destination 39290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!ret) 39390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("Memory Tracker logging initialized, " 39490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber "Memory Tracker v."vpx_mem_tracker_version"\n"); 39590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 39690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return ret; 39790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 39890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 39990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 40090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_set_log_func 40190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Sets a logging function to be used by the memory tracker. 40290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 40390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 40490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the logging type could not be set because logfunc was NULL 40590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 40690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint vpx_memory_tracker_set_log_func(void *userdata, 40790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber void(*logfunc)(void *userdata, 40890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber const char *fmt, va_list args)) 40990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 41090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int ret = -1; 41190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 41290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (logfunc) 41390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 41490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.type = -1; 41590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.userdata = userdata; 41690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.func = logfunc; 41790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 41890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 41990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 42090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber //output the version to the new logging destination 42190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!ret) 42290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("Memory Tracker logging initialized, " 42390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber "Memory Tracker v."vpx_mem_tracker_version"\n"); 42490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 42590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return ret; 42690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 42790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 42890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 42990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 43090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * END - Exposed library functions 43190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 43290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 43390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 43490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 43590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 43690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 43790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * Internal library functions 43890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * 43990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 44090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 44190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memtrack_log(const char *fmt, ...) 44290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 44390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber va_list list; 44490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 44590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber va_start(list, fmt); 44690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 44790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber switch (g_logging.type) 44890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 44990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case -1: 45090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 45190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_logging.func) 45290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_logging.func(g_logging.userdata, fmt, list); 45390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 45490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 45590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case 0: 45690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 45790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_logging.file) 45890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 45990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vfprintf(g_logging.file, fmt, list); 46090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber fflush(g_logging.file); 46190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 46290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 46390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 46490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(WIN32) && !defined(_WIN32_WCE) 46590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber case 1: 46690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 46790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char temp[1024]; 46890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber _vsnprintf(temp, sizeof(temp) / sizeof(char) - 1, fmt, list); 46990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber OutputDebugString(temp); 47090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 47190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 47290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 47390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber default: 47490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber break; 47590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 47690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 47790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber va_end(list); 47890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 47990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 48090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 48190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_dump() 48290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Dumps the current contents of the global memory allocation list 48390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 48490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_dump() 48590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 48690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int i = 0; 48790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *p = (memtrack.head ? memtrack.head->next : NULL); 48890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 48990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("\n_currently Allocated= %d; Max allocated= %d\n", 49090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.current_allocated, memtrack.max_allocated); 49190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 49290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber while (p) 49390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 49490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(WIN32) && !defined(_WIN32_WCE) 49590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 49690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber /*when using outputdebugstring, output filenames so they 49790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber can be clicked to be opened in visual studio*/ 49890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_logging.type == 1) 49990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file:\n" 50090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber " %s(%d):\n", i, 50190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->addr, i, p->size, 50290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->file, p->line); 50390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber else 50490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 50590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file: %s, line: %d\n", i, 50690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->addr, i, p->size, 50790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->file, p->line); 50890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 50990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef NDS_NITRO 51090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 51190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!(i % 20)) os_sleep(500); 51290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 51390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 51490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 51590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p = p->next; 51690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ++i; 51790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 51890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 51990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("\n"); 52090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 52190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 52290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 52390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_check_integrity(char* file, unsigned int file) 52490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber file - the file name where the check was placed 52590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber line - the line in file where the check was placed 52690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If a padding_size was supplied to vpx_memory_tracker_init() 52790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber this function will check ea. addr in the list verifying that 52890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber addr-padding_size and addr+padding_size is filled with pad_value 52990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 53090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void memory_tracker_check_integrity(char *file, unsigned int line) 53190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 53290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (memtrack.padding_size) 53390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 53490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int i, 53590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber index = 0; 53690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber unsigned char *p_show_me, 53790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * p_show_me2; 53890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber unsigned int tempme = memtrack.pad_value, 53990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber dead1, 54090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber dead2; 54190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber unsigned char *x_bounds; 54290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *p = memtrack.head->next; 54390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 54490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber while (p) 54590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 54690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber //x_bounds = (unsigned char*)p->addr; 54790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber //back up VPX_BYTE_ALIGNMENT 54890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber //x_bounds -= memtrack.padding_size; 54990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 55090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (p->padded) // can the bounds be checked? 55190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 55290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber /*yes, move to the address that was actually allocated 55390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber by the vpx_* calls*/ 55490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber x_bounds = (unsigned char *)(((size_t *)p->addr)[-1]); 55590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 55690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber for (i = 0; i < memtrack.padding_size; i += sizeof(unsigned int)) 55790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 55890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p_show_me = (x_bounds + i); 55990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p_show_me2 = (unsigned char *)(p->addr + p->size + i); 56090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 56190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber MEM_TRACK_MEMCPY(&dead1, p_show_me, sizeof(unsigned int)); 56290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber MEM_TRACK_MEMCPY(&dead2, p_show_me2, sizeof(unsigned int)); 56390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 56490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if ((dead1 != tempme) || (dead2 != tempme)) 56590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 56690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("\n[vpx_mem integrity check failed]:\n" 56790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber " index[%d,%d] {%s:%d} addr=0x%x, size=%d," 56890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber " file: %s, line: %d c0:0x%x c1:0x%x\n", 56990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber index, i, file, line, p->addr, p->size, p->file, 57090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->line, dead1, dead2); 57190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 57290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 57390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 57490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 57590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ++index; 57690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p = p->next; 57790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 57890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 57990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 58090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 58190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 58290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_add(size_t addr, unsigned int size, 58390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char * file, unsigned int line) 58490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Adds an address (addr), it's size, file and line number to our list. 58590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Adjusts the total bytes allocated and max bytes allocated if necessary. 58690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber If memory cannot be allocated the list will be destroyed. 58790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 58890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid memory_tracker_add(size_t addr, unsigned int size, 58990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber char *file, unsigned int line, 59090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int padded) 59190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 59290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!memory_tracker_lock_mutex()) 59390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 59490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *p; 59590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 59690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p = MEM_TRACK_MALLOC(sizeof(struct mem_block)); 59790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 59890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (p) 59990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 60090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->prev = memtrack.tail; 60190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->prev->next = p; 60290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->addr = addr; 60390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->size = size; 60490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->line = line; 60590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->file = file; 60690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->padded = padded; 60790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->next = NULL; 60890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 60990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.tail = p; 61090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 61190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.current_allocated += size; 61290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 61390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (memtrack.current_allocated > memtrack.max_allocated) 61490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.max_allocated = memtrack.current_allocated; 61590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 61690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber //memtrack_log("memory_tracker_add: added addr=0x%.8x\n", addr); 61790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 61890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex(); 61990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 62090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber else 62190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 62290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("memory_tracker_add: error allocating memory!\n"); 62390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex(); 62490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_destroy(); 62590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 62690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 62790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 62890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 62990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 63090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_remove(size_t addr) 63190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Removes an address and its corresponding size (if they exist) 63290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber from the memory tracker list and adjusts the current number 63390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber of bytes allocated. 63490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 63590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 63690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the mutex could not be locked 63790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -2: if the addr was not found in the list 63890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 63990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint memory_tracker_remove(size_t addr) 64090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 64190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int ret = -1; 64290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 64390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (!memory_tracker_lock_mutex()) 64490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 64590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *p; 64690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 64790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if ((p = memory_tracker_find(addr))) 64890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 64990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.current_allocated -= p->size; 65090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 65190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->prev->next = p->next; 65290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 65390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (p->next) 65490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p->next->prev = p->prev; 65590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber else 65690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack.tail = p->prev; 65790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 65890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 65990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber MEM_TRACK_FREE(p); 66090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 66190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber else 66290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 66390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (addr) 66490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("memory_tracker_remove(): addr not found in list," 66590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber " 0x%.8x\n", addr); 66690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 66790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = -2; 66890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 66990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 67090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex(); 67190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 67290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 67390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return ret; 67490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 67590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 67690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 67790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_find(size_t addr) 67890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Finds an address in our addrs list 67990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber NOTE: the mutex MUST be locked in the other internal 68090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber functions before calling this one. This avoids 68190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber the need for repeated locking and unlocking as in Remove 68290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Returns: pointer to the mem block if found, NULL otherwise 68390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 68490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic struct mem_block *memory_tracker_find(size_t addr) 68590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 68690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber struct mem_block *p = NULL; 68790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 68890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (memtrack.head) 68990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 69090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p = memtrack.head->next; 69190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 69290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber while (p && (p->addr != addr)) 69390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber p = p->next; 69490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 69590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 69690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return p; 69790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 69890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 69990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 70090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if !defined(NO_MUTEX) 70190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 70290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_lock_mutex() 70390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Locks the memory tracker mutex with a platform specific call 70490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Returns: 70590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: Success 70690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber <0: Failure, either the mutex was not initialized 70790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber or the call to lock the mutex failed 70890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 70990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_lock_mutex() 71090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 71190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int ret = -1; 71290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 71390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_b_mem_tracker_inited) 71490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 71590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 71690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 71790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = pthread_mutex_lock(&memtrack.mutex); 71890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 71990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = WaitForSingleObject(memtrack.mutex, INFINITE); 72090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 72190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = sem_take(memtrack.mutex, WAIT_FOREVER); 72290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NDS_NITRO) 72390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber os_lock_mutex(&memtrack.mutex); 72490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 72590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 72690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 72790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (ret) 72890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 72990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("memory_tracker_lock_mutex: mutex lock failed\n"); 73090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 73190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 73290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 73390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return ret; 73490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 73590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 73690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 73790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memory_tracker_unlock_mutex() 73890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Unlocks the memory tracker mutex with a platform specific call 73990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Returns: 74090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: Success 74190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber <0: Failure, either the mutex was not initialized 74290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber or the call to unlock the mutex failed 74390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 74490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int memory_tracker_unlock_mutex() 74590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 74690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber int ret = -1; 74790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 74890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_b_mem_tracker_inited) 74990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 75090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 75190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if HAVE_PTHREAD_H 75290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = pthread_mutex_unlock(&memtrack.mutex); 75390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(WIN32) || defined(_WIN32_WCE) 75490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = !ReleaseMutex(memtrack.mutex); 75590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(VXWORKS) 75690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = sem_give(memtrack.mutex); 75790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#elif defined(NDS_NITRO) 75890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber os_unlock_mutex(&memtrack.mutex); 75990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ret = 0; 76090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 76190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 76290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (ret) 76390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber { 76490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber memtrack_log("memory_tracker_unlock_mutex: mutex unlock failed\n"); 76590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 76690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber } 76790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 76890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return ret; 76990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 77090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 77190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 77290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* 77390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber vpx_memory_tracker_set_functions 77490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 77590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Sets the function pointers for the standard library functions. 77690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 77790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber Return: 77890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 0: on success 77990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber -1: if the use global function pointers is not set. 78090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*/ 78190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l 78290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , mem_track_calloc_func g_calloc_l 78390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , mem_track_realloc_func g_realloc_l 78490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , mem_track_free_func g_free_l 78590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , mem_track_memcpy_func g_memcpy_l 78690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , mem_track_memset_func g_memset_l 78790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber , mem_track_memmove_func g_memmove_l) 78890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{ 78990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if USE_GLOBAL_FUNCTION_POINTERS 79090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 79190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_malloc_l) 79290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_malloc = g_malloc_l; 79390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 79490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_calloc_l) 79590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_calloc = g_calloc_l; 79690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 79790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_realloc_l) 79890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_realloc = g_realloc_l; 79990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 80090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_free_l) 80190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_free = g_free_l; 80290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 80390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_memcpy_l) 80490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_memcpy = g_memcpy_l; 80590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 80690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_memset_l) 80790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_memset = g_memset_l; 80890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 80990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber if (g_memmove_l) 81090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber g_memmove = g_memmove_l; 81190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 81290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return 0; 81390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else 81490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber (void)g_malloc_l; 81590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber (void)g_calloc_l; 81690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber (void)g_realloc_l; 81790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber (void)g_free_l; 81890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber (void)g_memcpy_l; 81990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber (void)g_memset_l; 82090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber (void)g_memmove_l; 82190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber return -1; 82290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif 82390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} 824