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