Index: source/libvpx/vpx_mem/vpx_mem_tracker.c |
diff --git a/source/libvpx/vpx_mem/vpx_mem_tracker.c b/source/libvpx/vpx_mem/vpx_mem_tracker.c |
deleted file mode 100644 |
index 613e8a16b0e6f36a29ed2172bc9212e017dc62b7..0000000000000000000000000000000000000000 |
--- a/source/libvpx/vpx_mem/vpx_mem_tracker.c |
+++ /dev/null |
@@ -1,740 +0,0 @@ |
-/* |
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
- |
-/* |
- vpx_mem_tracker.c |
- |
- jwz 2003-09-30: |
- Stores a list of addreses, their size, and file and line they came from. |
- All exposed lib functions are prefaced by vpx_ and allow the global list |
- to be thread safe. |
- Current supported platforms are: |
- Linux, Win32, win_ce and vx_works |
- Further support can be added by defining the platform specific mutex |
- in the memory_tracker struct as well as calls to create/destroy/lock/unlock |
- the mutex in vpx_memory_tracker_init/Destroy and memory_tracker_lock_mutex/unlock_mutex |
-*/ |
-#include "./vpx_config.h" |
- |
-#if defined(__uClinux__) |
-# include <lddk.h> |
-#endif |
- |
-#if HAVE_PTHREAD_H |
-# include <pthread.h> |
-#elif defined(WIN32) || defined(_WIN32_WCE) |
-# define WIN32_LEAN_AND_MEAN |
-# include <windows.h> |
-# include <winbase.h> |
-#elif defined(VXWORKS) |
-# include <sem_lib.h> |
-#endif |
- |
-#include <stdio.h> |
-#include <stdlib.h> |
-#include <string.h> // VXWORKS doesn't have a malloc/memory.h file, |
-// this should pull in malloc,free,etc. |
-#include <stdarg.h> |
- |
-#include "include/vpx_mem_tracker.h" |
- |
-#undef vpx_malloc // undefine any vpx_mem macros that may affect calls to |
-#undef vpx_free // memory functions in this file |
-#undef vpx_memcpy |
-#undef vpx_memset |
- |
- |
-#ifndef USE_GLOBAL_FUNCTION_POINTERS |
-# define USE_GLOBAL_FUNCTION_POINTERS 0 // use function pointers instead of compiled functions. |
-#endif |
- |
-#if USE_GLOBAL_FUNCTION_POINTERS |
-static mem_track_malloc_func g_malloc = malloc; |
-static mem_track_calloc_func g_calloc = calloc; |
-static mem_track_realloc_func g_realloc = realloc; |
-static mem_track_free_func g_free = free; |
-static mem_track_memcpy_func g_memcpy = memcpy; |
-static mem_track_memset_func g_memset = memset; |
-static mem_track_memmove_func g_memmove = memmove; |
-# define MEM_TRACK_MALLOC g_malloc |
-# define MEM_TRACK_FREE g_free |
-# define MEM_TRACK_MEMCPY g_memcpy |
-# define MEM_TRACK_MEMSET g_memset |
-#else |
-# define MEM_TRACK_MALLOC vpx_malloc |
-# define MEM_TRACK_FREE vpx_free |
-# define MEM_TRACK_MEMCPY vpx_memcpy |
-# define MEM_TRACK_MEMSET vpx_memset |
-#endif // USE_GLOBAL_FUNCTION_POINTERS |
- |
-/* prototypes for internal library functions */ |
-static void memtrack_log(const char *fmt, ...); |
-static void memory_tracker_dump(); |
-static void memory_tracker_check_integrity(char *file, unsigned int line); |
-static void memory_tracker_add(size_t addr, unsigned int size, |
- char *file, unsigned int line, |
- int padded); |
-static int memory_tracker_remove(size_t addr); |
-static struct mem_block *memory_tracker_find(size_t addr); |
- |
-#if defined(NO_MUTEX) |
-# define memory_tracker_lock_mutex() (!g_b_mem_tracker_inited) |
-# define memory_tracker_unlock_mutex() |
-#else |
-static int memory_tracker_lock_mutex(); |
-static int memory_tracker_unlock_mutex(); |
-#endif |
- |
-#ifndef VPX_NO_GLOBALS |
-struct memory_tracker { |
- struct mem_block *head, |
- * tail; |
- int len, |
- totalsize; |
- unsigned int current_allocated, |
- max_allocated; |
- |
-#if HAVE_PTHREAD_H |
- pthread_mutex_t mutex; |
-#elif defined(WIN32) || defined(_WIN32_WCE) |
- HANDLE mutex; |
-#elif defined(VXWORKS) |
- SEM_ID mutex; |
-#elif defined(NO_MUTEX) |
-#else |
-#error "No mutex type defined for this platform!" |
-#endif |
- |
- int padding_size, |
- pad_value; |
-}; |
- |
-static struct memory_tracker memtrack; // our global memory allocation list |
-static int g_b_mem_tracker_inited = 0; // indicates whether the global list has |
-// been initialized (1:yes/0:no) |
-static struct { |
- FILE *file; |
- int type; |
- void (*func)(void *userdata, const char *fmt, va_list args); |
- void *userdata; |
-} g_logging = {NULL, 0, NULL, NULL}; |
-#else |
-# include "vpx_global_handling.h" |
-#define g_b_mem_tracker_inited vpxglobalm(vpxmem,g_b_mem_tracker_inited) |
-#define g_logging vpxglobalm(vpxmem,g_logging) |
-#define memtrack vpxglobalm(vpxmem,memtrack) |
-#endif // #ifndef VPX_NO_GLOBALS |
- |
-extern void *vpx_malloc(size_t size); |
-extern void vpx_free(void *memblk); |
-extern void *vpx_memcpy(void *dest, const void *src, size_t length); |
-extern void *vpx_memset(void *dest, int val, size_t length); |
- |
-/* |
- * |
- * Exposed library functions |
- * |
-*/ |
- |
-/* |
- vpx_memory_tracker_init(int padding_size, int pad_value) |
- padding_size - the size of the padding before and after each mem addr. |
- Values > 0 indicate that integrity checks can be performed |
- by inspecting these areas. |
- pad_value - the initial value within the padding area before and after |
- each mem addr. |
- |
- Initializes global memory tracker structure |
- Allocates the head of the list |
-*/ |
-int vpx_memory_tracker_init(int padding_size, int pad_value) { |
- if (!g_b_mem_tracker_inited) { |
- if ((memtrack.head = (struct mem_block *) |
- MEM_TRACK_MALLOC(sizeof(struct mem_block)))) { |
- int ret; |
- |
- MEM_TRACK_MEMSET(memtrack.head, 0, sizeof(struct mem_block)); |
- |
- memtrack.tail = memtrack.head; |
- |
- memtrack.current_allocated = 0; |
- memtrack.max_allocated = 0; |
- |
- memtrack.padding_size = padding_size; |
- memtrack.pad_value = pad_value; |
- |
-#if HAVE_PTHREAD_H |
- ret = pthread_mutex_init(&memtrack.mutex, |
- NULL); /*mutex attributes (NULL=default)*/ |
-#elif defined(WIN32) || defined(_WIN32_WCE) |
- memtrack.mutex = CreateMutex(NULL, /*security attributes*/ |
- FALSE, /*we don't want initial ownership*/ |
- NULL); /*mutex name*/ |
- ret = !memtrack.mutex; |
-#elif defined(VXWORKS) |
- memtrack.mutex = sem_bcreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority based mutex*/ |
- SEM_FULL); /*SEM_FULL initial state is unlocked*/ |
- ret = !memtrack.mutex; |
-#elif defined(NO_MUTEX) |
- ret = 0; |
-#endif |
- |
- if (ret) { |
- memtrack_log("vpx_memory_tracker_init: Error creating mutex!\n"); |
- |
- MEM_TRACK_FREE(memtrack.head); |
- memtrack.head = NULL; |
- } else { |
- memtrack_log("Memory Tracker init'd, v."vpx_mem_tracker_version" pad_size:%d pad_val:0x%x %d\n" |
-, padding_size |
-, pad_value |
-, pad_value); |
- g_b_mem_tracker_inited = 1; |
- } |
- } |
- } |
- |
- return g_b_mem_tracker_inited; |
-} |
- |
-/* |
- vpx_memory_tracker_destroy() |
- If our global struct was initialized zeros out all its members, |
- frees memory and destroys it's mutex |
-*/ |
-void vpx_memory_tracker_destroy() { |
- if (!memory_tracker_lock_mutex()) { |
- struct mem_block *p = memtrack.head, |
- * p2 = memtrack.head; |
- |
- memory_tracker_dump(); |
- |
- while (p) { |
- p2 = p; |
- p = p->next; |
- |
- MEM_TRACK_FREE(p2); |
- } |
- |
- memtrack.head = NULL; |
- memtrack.tail = NULL; |
- memtrack.len = 0; |
- memtrack.current_allocated = 0; |
- memtrack.max_allocated = 0; |
- |
- if (!g_logging.type && g_logging.file && g_logging.file != stderr) { |
- fclose(g_logging.file); |
- g_logging.file = NULL; |
- } |
- |
- memory_tracker_unlock_mutex(); |
- |
- g_b_mem_tracker_inited = 0; |
- } |
-} |
- |
-/* |
- vpx_memory_tracker_add(size_t addr, unsigned int size, |
- char * file, unsigned int line) |
- addr - memory address to be added to list |
- size - size of addr |
- file - the file addr was referenced from |
- line - the line in file addr was referenced from |
- Adds memory address addr, it's size, file and line it came from |
- to the global list via the thread safe internal library function |
-*/ |
-void vpx_memory_tracker_add(size_t addr, unsigned int size, |
- char *file, unsigned int line, |
- int padded) { |
- memory_tracker_add(addr, size, file, line, padded); |
-} |
- |
-/* |
- vpx_memory_tracker_remove(size_t addr) |
- addr - memory address to be removed from list |
- Removes addr from the global list via the thread safe |
- internal remove function |
- Return: |
- Same as described for memory_tracker_remove |
-*/ |
-int vpx_memory_tracker_remove(size_t addr) { |
- return memory_tracker_remove(addr); |
-} |
- |
-/* |
- vpx_memory_tracker_find(size_t addr) |
- addr - address to be found in list |
- Return: |
- If found, pointer to the memory block that matches addr |
- NULL otherwise |
-*/ |
-struct mem_block *vpx_memory_tracker_find(size_t addr) { |
- struct mem_block *p = NULL; |
- |
- if (!memory_tracker_lock_mutex()) { |
- p = memory_tracker_find(addr); |
- memory_tracker_unlock_mutex(); |
- } |
- |
- return p; |
-} |
- |
-/* |
- vpx_memory_tracker_dump() |
- Locks the memory tracker's mutex and calls the internal |
- library function to dump the current contents of the |
- global memory allocation list |
-*/ |
-void vpx_memory_tracker_dump() { |
- if (!memory_tracker_lock_mutex()) { |
- memory_tracker_dump(); |
- memory_tracker_unlock_mutex(); |
- } |
-} |
- |
-/* |
- vpx_memory_tracker_check_integrity(char* file, unsigned int line) |
- file - The file name where the check was placed |
- line - The line in file where the check was placed |
- Locks the memory tracker's mutex and calls the internal |
- integrity check function to inspect every address in the global |
- memory allocation list |
-*/ |
-void vpx_memory_tracker_check_integrity(char *file, unsigned int line) { |
- if (!memory_tracker_lock_mutex()) { |
- memory_tracker_check_integrity(file, line); |
- memory_tracker_unlock_mutex(); |
- } |
-} |
- |
-/* |
- vpx_memory_tracker_set_log_type |
- Sets the logging type for the memory tracker. Based on the value it will |
- direct its output to the appropriate place. |
- Return: |
- 0: on success |
- -1: if the logging type could not be set, because the value was invalid |
- or because a file could not be opened |
-*/ |
-int vpx_memory_tracker_set_log_type(int type, char *option) { |
- int ret = -1; |
- |
- switch (type) { |
- case 0: |
- g_logging.type = 0; |
- |
- if (!option) { |
- g_logging.file = stderr; |
- ret = 0; |
- } else { |
- if ((g_logging.file = fopen((char *)option, "w"))) |
- ret = 0; |
- } |
- |
- break; |
-#if defined(WIN32) && !defined(_WIN32_WCE) |
- case 1: |
- g_logging.type = type; |
- ret = 0; |
- break; |
-#endif |
- default: |
- break; |
- } |
- |
- // output the version to the new logging destination |
- if (!ret) |
- memtrack_log("Memory Tracker logging initialized, " |
- "Memory Tracker v."vpx_mem_tracker_version"\n"); |
- |
- return ret; |
-} |
- |
-/* |
- vpx_memory_tracker_set_log_func |
- Sets a logging function to be used by the memory tracker. |
- Return: |
- 0: on success |
- -1: if the logging type could not be set because logfunc was NULL |
-*/ |
-int vpx_memory_tracker_set_log_func(void *userdata, |
- void(*logfunc)(void *userdata, |
- const char *fmt, va_list args)) { |
- int ret = -1; |
- |
- if (logfunc) { |
- g_logging.type = -1; |
- g_logging.userdata = userdata; |
- g_logging.func = logfunc; |
- ret = 0; |
- } |
- |
- // output the version to the new logging destination |
- if (!ret) |
- memtrack_log("Memory Tracker logging initialized, " |
- "Memory Tracker v."vpx_mem_tracker_version"\n"); |
- |
- return ret; |
-} |
- |
-/* |
- * |
- * END - Exposed library functions |
- * |
-*/ |
- |
- |
-/* |
- * |
- * Internal library functions |
- * |
-*/ |
- |
-static void memtrack_log(const char *fmt, ...) { |
- va_list list; |
- |
- va_start(list, fmt); |
- |
- switch (g_logging.type) { |
- case -1: |
- |
- if (g_logging.func) |
- g_logging.func(g_logging.userdata, fmt, list); |
- |
- break; |
- case 0: |
- |
- if (g_logging.file) { |
- vfprintf(g_logging.file, fmt, list); |
- fflush(g_logging.file); |
- } |
- |
- break; |
-#if defined(WIN32) && !defined(_WIN32_WCE) |
- case 1: { |
- char temp[1024]; |
- _vsnprintf(temp, sizeof(temp) / sizeof(char) - 1, fmt, list); |
- OutputDebugString(temp); |
- } |
- break; |
-#endif |
- default: |
- break; |
- } |
- |
- va_end(list); |
-} |
- |
-/* |
- memory_tracker_dump() |
- Dumps the current contents of the global memory allocation list |
-*/ |
-static void memory_tracker_dump() { |
- int i = 0; |
- struct mem_block *p = (memtrack.head ? memtrack.head->next : NULL); |
- |
- memtrack_log("\n_currently Allocated= %d; Max allocated= %d\n", |
- memtrack.current_allocated, memtrack.max_allocated); |
- |
- while (p) { |
-#if defined(WIN32) && !defined(_WIN32_WCE) |
- |
- /*when using outputdebugstring, output filenames so they |
- can be clicked to be opened in visual studio*/ |
- if (g_logging.type == 1) |
- memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file:\n" |
- " %s(%d):\n", i, |
- p->addr, i, p->size, |
- p->file, p->line); |
- else |
-#endif |
- memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file: %s, line: %d\n", i, |
- p->addr, i, p->size, |
- p->file, p->line); |
- |
- p = p->next; |
- ++i; |
- } |
- |
- memtrack_log("\n"); |
-} |
- |
-/* |
- memory_tracker_check_integrity(char* file, unsigned int file) |
- file - the file name where the check was placed |
- line - the line in file where the check was placed |
- If a padding_size was supplied to vpx_memory_tracker_init() |
- this function will check ea. addr in the list verifying that |
- addr-padding_size and addr+padding_size is filled with pad_value |
-*/ |
-static void memory_tracker_check_integrity(char *file, unsigned int line) { |
- if (memtrack.padding_size) { |
- int i, |
- index = 0; |
- unsigned char *p_show_me, |
- * p_show_me2; |
- unsigned int tempme = memtrack.pad_value, |
- dead1, |
- dead2; |
- unsigned char *x_bounds; |
- struct mem_block *p = memtrack.head->next; |
- |
- while (p) { |
- // x_bounds = (unsigned char*)p->addr; |
- // back up VPX_BYTE_ALIGNMENT |
- // x_bounds -= memtrack.padding_size; |
- |
- if (p->padded) { // can the bounds be checked? |
- /*yes, move to the address that was actually allocated |
- by the vpx_* calls*/ |
- x_bounds = (unsigned char *)(((size_t *)p->addr)[-1]); |
- |
- for (i = 0; i < memtrack.padding_size; i += sizeof(unsigned int)) { |
- p_show_me = (x_bounds + i); |
- p_show_me2 = (unsigned char *)(p->addr + p->size + i); |
- |
- MEM_TRACK_MEMCPY(&dead1, p_show_me, sizeof(unsigned int)); |
- MEM_TRACK_MEMCPY(&dead2, p_show_me2, sizeof(unsigned int)); |
- |
- if ((dead1 != tempme) || (dead2 != tempme)) { |
- memtrack_log("\n[vpx_mem integrity check failed]:\n" |
- " index[%d,%d] {%s:%d} addr=0x%x, size=%d," |
- " file: %s, line: %d c0:0x%x c1:0x%x\n", |
- index, i, file, line, p->addr, p->size, p->file, |
- p->line, dead1, dead2); |
- } |
- } |
- } |
- |
- ++index; |
- p = p->next; |
- } |
- } |
-} |
- |
-/* |
- memory_tracker_add(size_t addr, unsigned int size, |
- char * file, unsigned int line) |
- Adds an address (addr), it's size, file and line number to our list. |
- Adjusts the total bytes allocated and max bytes allocated if necessary. |
- If memory cannot be allocated the list will be destroyed. |
-*/ |
-void memory_tracker_add(size_t addr, unsigned int size, |
- char *file, unsigned int line, |
- int padded) { |
- if (!memory_tracker_lock_mutex()) { |
- struct mem_block *p; |
- |
- p = MEM_TRACK_MALLOC(sizeof(struct mem_block)); |
- |
- if (p) { |
- p->prev = memtrack.tail; |
- p->prev->next = p; |
- p->addr = addr; |
- p->size = size; |
- p->line = line; |
- p->file = file; |
- p->padded = padded; |
- p->next = NULL; |
- |
- memtrack.tail = p; |
- |
- memtrack.current_allocated += size; |
- |
- if (memtrack.current_allocated > memtrack.max_allocated) |
- memtrack.max_allocated = memtrack.current_allocated; |
- |
- // memtrack_log("memory_tracker_add: added addr=0x%.8x\n", addr); |
- |
- memory_tracker_unlock_mutex(); |
- } else { |
- memtrack_log("memory_tracker_add: error allocating memory!\n"); |
- memory_tracker_unlock_mutex(); |
- vpx_memory_tracker_destroy(); |
- } |
- } |
-} |
- |
-/* |
- memory_tracker_remove(size_t addr) |
- Removes an address and its corresponding size (if they exist) |
- from the memory tracker list and adjusts the current number |
- of bytes allocated. |
- Return: |
- 0: on success |
- -1: if the mutex could not be locked |
- -2: if the addr was not found in the list |
-*/ |
-int memory_tracker_remove(size_t addr) { |
- int ret = -1; |
- |
- if (!memory_tracker_lock_mutex()) { |
- struct mem_block *p; |
- |
- if ((p = memory_tracker_find(addr))) { |
- memtrack.current_allocated -= p->size; |
- |
- p->prev->next = p->next; |
- |
- if (p->next) |
- p->next->prev = p->prev; |
- else |
- memtrack.tail = p->prev; |
- |
- ret = 0; |
- MEM_TRACK_FREE(p); |
- } else { |
- if (addr) |
- memtrack_log("memory_tracker_remove(): addr not found in list," |
- " 0x%.8x\n", addr); |
- |
- ret = -2; |
- } |
- |
- memory_tracker_unlock_mutex(); |
- } |
- |
- return ret; |
-} |
- |
-/* |
- memory_tracker_find(size_t addr) |
- Finds an address in our addrs list |
- NOTE: the mutex MUST be locked in the other internal |
- functions before calling this one. This avoids |
- the need for repeated locking and unlocking as in Remove |
- Returns: pointer to the mem block if found, NULL otherwise |
-*/ |
-static struct mem_block *memory_tracker_find(size_t addr) { |
- struct mem_block *p = NULL; |
- |
- if (memtrack.head) { |
- p = memtrack.head->next; |
- |
- while (p && (p->addr != addr)) |
- p = p->next; |
- } |
- |
- return p; |
-} |
- |
- |
-#if !defined(NO_MUTEX) |
-/* |
- memory_tracker_lock_mutex() |
- Locks the memory tracker mutex with a platform specific call |
- Returns: |
- 0: Success |
- <0: Failure, either the mutex was not initialized |
- or the call to lock the mutex failed |
-*/ |
-static int memory_tracker_lock_mutex() { |
- int ret = -1; |
- |
- if (g_b_mem_tracker_inited) { |
- |
-#if HAVE_PTHREAD_H |
- ret = pthread_mutex_lock(&memtrack.mutex); |
-#elif defined(WIN32) || defined(_WIN32_WCE) |
- ret = WaitForSingleObject(memtrack.mutex, INFINITE); |
-#elif defined(VXWORKS) |
- ret = sem_take(memtrack.mutex, WAIT_FOREVER); |
-#endif |
- |
- if (ret) { |
- memtrack_log("memory_tracker_lock_mutex: mutex lock failed\n"); |
- } |
- } |
- |
- return ret; |
-} |
- |
-/* |
- memory_tracker_unlock_mutex() |
- Unlocks the memory tracker mutex with a platform specific call |
- Returns: |
- 0: Success |
- <0: Failure, either the mutex was not initialized |
- or the call to unlock the mutex failed |
-*/ |
-static int memory_tracker_unlock_mutex() { |
- int ret = -1; |
- |
- if (g_b_mem_tracker_inited) { |
- |
-#if HAVE_PTHREAD_H |
- ret = pthread_mutex_unlock(&memtrack.mutex); |
-#elif defined(WIN32) || defined(_WIN32_WCE) |
- ret = !ReleaseMutex(memtrack.mutex); |
-#elif defined(VXWORKS) |
- ret = sem_give(memtrack.mutex); |
-#endif |
- |
- if (ret) { |
- memtrack_log("memory_tracker_unlock_mutex: mutex unlock failed\n"); |
- } |
- } |
- |
- return ret; |
-} |
-#endif |
- |
-/* |
- vpx_memory_tracker_set_functions |
- |
- Sets the function pointers for the standard library functions. |
- |
- Return: |
- 0: on success |
- -1: if the use global function pointers is not set. |
-*/ |
-int vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l |
-, mem_track_calloc_func g_calloc_l |
-, mem_track_realloc_func g_realloc_l |
-, mem_track_free_func g_free_l |
-, mem_track_memcpy_func g_memcpy_l |
-, mem_track_memset_func g_memset_l |
-, mem_track_memmove_func g_memmove_l) { |
-#if USE_GLOBAL_FUNCTION_POINTERS |
- |
- if (g_malloc_l) |
- g_malloc = g_malloc_l; |
- |
- if (g_calloc_l) |
- g_calloc = g_calloc_l; |
- |
- if (g_realloc_l) |
- g_realloc = g_realloc_l; |
- |
- if (g_free_l) |
- g_free = g_free_l; |
- |
- if (g_memcpy_l) |
- g_memcpy = g_memcpy_l; |
- |
- if (g_memset_l) |
- g_memset = g_memset_l; |
- |
- if (g_memmove_l) |
- g_memmove = g_memmove_l; |
- |
- return 0; |
-#else |
- (void)g_malloc_l; |
- (void)g_calloc_l; |
- (void)g_realloc_l; |
- (void)g_free_l; |
- (void)g_memcpy_l; |
- (void)g_memset_l; |
- (void)g_memmove_l; |
- return -1; |
-#endif |
-} |