vpx_mem: remove mem tracker
vestigial. there are tools better suited for this Change-Id: I7a72a2cfe32377f07c8cd0973ddb18842720a225
This commit is contained in:
parent
4a29474c83
commit
4659e3644f
3
configure
vendored
3
configure
vendored
@ -40,7 +40,6 @@ Advanced options:
|
||||
${toggle_vp8} VP8 codec support
|
||||
${toggle_vp9} VP9 codec support
|
||||
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
|
||||
${toggle_mem_tracker} track memory usage
|
||||
${toggle_postproc} postprocessing
|
||||
${toggle_vp9_postproc} vp9 specific postprocessing
|
||||
${toggle_multithread} multithreaded encoding and decoding
|
||||
@ -296,7 +295,6 @@ CONFIG_LIST="
|
||||
codec_srcs
|
||||
debug_libs
|
||||
fast_unaligned
|
||||
mem_tracker
|
||||
|
||||
dequant_tokens
|
||||
dc_recon
|
||||
@ -371,7 +369,6 @@ CMDLINE_SELECT="
|
||||
${CODECS}
|
||||
${CODEC_FAMILIES}
|
||||
static_msvcrt
|
||||
mem_tracker
|
||||
spatial_resampling
|
||||
realtime_only
|
||||
onthefly_bitpacking
|
||||
|
@ -13,21 +13,10 @@
|
||||
#define VPX_MEM_INCLUDE_VPX_MEM_INTRNL_H_
|
||||
#include "./vpx_config.h"
|
||||
|
||||
#ifndef CONFIG_MEM_TRACKER
|
||||
# define CONFIG_MEM_TRACKER 1 /*include xvpx_* calls in the lib*/
|
||||
#endif
|
||||
|
||||
#ifndef USE_GLOBAL_FUNCTION_POINTERS
|
||||
# define USE_GLOBAL_FUNCTION_POINTERS 0 /*use function pointers instead of compiled functions.*/
|
||||
#endif
|
||||
|
||||
#if CONFIG_MEM_TRACKER
|
||||
# include "vpx_mem_tracker.h"
|
||||
# if VPX_MEM_TRACKER_VERSION_CHIEF != 2 || VPX_MEM_TRACKER_VERSION_MAJOR != 5
|
||||
# error "vpx_mem requires memory tracker version 2.5 to track memory usage"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define ADDRESS_STORAGE_SIZE sizeof(size_t)
|
||||
|
||||
#ifndef DEFAULT_ALIGNMENT
|
||||
@ -40,41 +29,6 @@ than vpx_memalign*/
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_MEM_TRACKER
|
||||
# define TRY_BOUNDS_CHECK 1 /*when set to 1 pads each allocation,
|
||||
integrity can be checked using
|
||||
vpx_memory_tracker_check_integrity
|
||||
or on free by defining*/
|
||||
/*TRY_BOUNDS_CHECK_ON_FREE*/
|
||||
#else
|
||||
# define TRY_BOUNDS_CHECK 0
|
||||
#endif /*CONFIG_MEM_TRACKER*/
|
||||
|
||||
#if TRY_BOUNDS_CHECK
|
||||
# define TRY_BOUNDS_CHECK_ON_FREE 0 /*checks mem integrity on every
|
||||
free, very expensive*/
|
||||
# define BOUNDS_CHECK_VALUE 0xdeadbeef /*value stored before/after ea.
|
||||
mem addr for bounds checking*/
|
||||
# define BOUNDS_CHECK_PAD_SIZE 32 /*size of the padding before and
|
||||
after ea allocation to be filled
|
||||
with BOUNDS_CHECK_VALUE.
|
||||
this should be a multiple of 4*/
|
||||
#else
|
||||
# define BOUNDS_CHECK_VALUE 0
|
||||
# define BOUNDS_CHECK_PAD_SIZE 0
|
||||
#endif /*TRY_BOUNDS_CHECK*/
|
||||
|
||||
#ifndef REMOVE_PRINTFS
|
||||
# define REMOVE_PRINTFS 0
|
||||
#endif
|
||||
|
||||
/* Should probably use a vpx_mem logger function. */
|
||||
#if REMOVE_PRINTFS
|
||||
# define _P(x)
|
||||
#else
|
||||
# define _P(x) x
|
||||
#endif
|
||||
|
||||
/*returns an addr aligned to the byte boundary specified by align*/
|
||||
#define align_addr(addr,align) (void*)(((size_t)(addr) + ((align) - 1)) & (size_t)-(align))
|
||||
|
||||
|
@ -1,179 +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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VPX_MEM_INCLUDE_VPX_MEM_TRACKER_H_
|
||||
#define VPX_MEM_INCLUDE_VPX_MEM_TRACKER_H_
|
||||
|
||||
/* vpx_mem_tracker version info */
|
||||
#define vpx_mem_tracker_version "2.5.1.1"
|
||||
|
||||
#define VPX_MEM_TRACKER_VERSION_CHIEF 2
|
||||
#define VPX_MEM_TRACKER_VERSION_MAJOR 5
|
||||
#define VPX_MEM_TRACKER_VERSION_MINOR 1
|
||||
#define VPX_MEM_TRACKER_VERSION_PATCH 1
|
||||
/* END - vpx_mem_tracker version info */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
struct mem_block {
|
||||
size_t addr;
|
||||
unsigned int size,
|
||||
line;
|
||||
char *file;
|
||||
struct mem_block *prev,
|
||||
* next;
|
||||
|
||||
int padded; // This mem_block has padding for integrity checks.
|
||||
// As of right now, this should only be 0 if
|
||||
// using vpx_mem_alloc to allocate cache memory.
|
||||
// 2005-01-11 tjf
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
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 the memory tracker interface. Should be called before any
|
||||
other calls to the memory tracker.
|
||||
*/
|
||||
int vpx_memory_tracker_init(int padding_size, int pad_value);
|
||||
|
||||
/*
|
||||
vpx_memory_tracker_destroy()
|
||||
Deinitializes the memory tracker interface
|
||||
*/
|
||||
void vpx_memory_tracker_destroy();
|
||||
|
||||
/*
|
||||
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 memory tracker allocation table
|
||||
*/
|
||||
void vpx_memory_tracker_add(size_t addr, unsigned int size,
|
||||
char *file, unsigned int line,
|
||||
int padded);
|
||||
|
||||
/*
|
||||
vpx_memory_tracker_add(size_t addr, unsigned int size, char * file, unsigned int line)
|
||||
addr - memory address to be added to be removed
|
||||
padded - if 0, disables bounds checking on this memory block even if bounds
|
||||
checking is enabled. (for example, when allocating cache memory, we still want
|
||||
to check for memory leaks, but we do not waste cache space for bounds check padding)
|
||||
Removes the specified address from the memory tracker's allocation
|
||||
table
|
||||
Return:
|
||||
0: on success
|
||||
-1: if memory allocation table's mutex could not be locked
|
||||
-2: if the addr was not found in the list
|
||||
*/
|
||||
int vpx_memory_tracker_remove(size_t addr);
|
||||
|
||||
/*
|
||||
vpx_memory_tracker_find(unsigned int addr)
|
||||
addr - address to be found in the memory tracker's
|
||||
allocation table
|
||||
Return:
|
||||
If found, pointer to the memory block that matches addr
|
||||
NULL otherwise
|
||||
*/
|
||||
struct mem_block *vpx_memory_tracker_find(size_t addr);
|
||||
|
||||
/*
|
||||
vpx_memory_tracker_dump()
|
||||
Dumps the current contents of the memory
|
||||
tracker allocation table
|
||||
*/
|
||||
void vpx_memory_tracker_dump();
|
||||
|
||||
/*
|
||||
vpx_memory_tracker_check_integrity()
|
||||
If a padding_size was provided to vpx_memory_tracker_init()
|
||||
This function will verify that the region before and after each
|
||||
memory address contains the specified pad_value. Should the check
|
||||
fail, the filename and line of the check will be printed out.
|
||||
*/
|
||||
void vpx_memory_tracker_check_integrity(char *file, unsigned int line);
|
||||
|
||||
/*
|
||||
vpx_memory_tracker_set_log_type
|
||||
type - value representing the logging type to use
|
||||
option - type specific option. This will be interpreted differently
|
||||
based on the type.
|
||||
Sets the logging type for the memory tracker.
|
||||
Values currently supported:
|
||||
0: if option is NULL, log to stderr, otherwise interpret option as a
|
||||
filename and attempt to open it.
|
||||
1: Use output_debug_string (WIN32 only), option ignored
|
||||
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);
|
||||
|
||||
/*
|
||||
vpx_memory_tracker_set_log_func
|
||||
userdata - ptr to be passed to the supplied logfunc, can be NULL
|
||||
logfunc - the logging function to be used to output data from
|
||||
vpx_memory_track_dump/check_integrity
|
||||
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));
|
||||
|
||||
/* Wrappers to standard library functions. */
|
||||
typedef void *(* mem_track_malloc_func)(size_t);
|
||||
typedef void *(* mem_track_calloc_func)(size_t, size_t);
|
||||
typedef void *(* mem_track_realloc_func)(void *, size_t);
|
||||
typedef void (* mem_track_free_func)(void *);
|
||||
typedef void *(* mem_track_memcpy_func)(void *, const void *, size_t);
|
||||
typedef void *(* mem_track_memset_func)(void *, int, size_t);
|
||||
typedef void *(* mem_track_memmove_func)(void *, const void *, size_t);
|
||||
|
||||
/*
|
||||
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 defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VPX_MEM_INCLUDE_VPX_MEM_TRACKER_H_
|
@ -18,15 +18,6 @@
|
||||
#include "include/vpx_mem_intrnl.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
#if CONFIG_MEM_TRACKER
|
||||
#ifndef VPX_NO_GLOBALS
|
||||
static unsigned long g_alloc_count = 0;
|
||||
#else
|
||||
#include "vpx_global_handling.h"
|
||||
#define g_alloc_count vpxglobalm(vpxmem,g_alloc_count)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_GLOBAL_FUNCTION_POINTERS
|
||||
struct GLOBAL_FUNC_POINTERS {
|
||||
g_malloc_func g_malloc;
|
||||
@ -134,194 +125,6 @@ void vpx_free(void *memblk) {
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_MEM_TRACKER
|
||||
void *xvpx_memalign(size_t align, size_t size, char *file, int line) {
|
||||
#if TRY_BOUNDS_CHECK
|
||||
unsigned char *x_bounds;
|
||||
#endif
|
||||
|
||||
void *x;
|
||||
|
||||
if (g_alloc_count == 0) {
|
||||
#if TRY_BOUNDS_CHECK
|
||||
int i_rv = vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE);
|
||||
#else
|
||||
int i_rv = vpx_memory_tracker_init(0, 0);
|
||||
#endif
|
||||
|
||||
if (i_rv < 0) {
|
||||
_P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");)
|
||||
}
|
||||
}
|
||||
|
||||
#if TRY_BOUNDS_CHECK
|
||||
{
|
||||
int i;
|
||||
unsigned int tempme = BOUNDS_CHECK_VALUE;
|
||||
|
||||
x_bounds = vpx_memalign(align, size + (BOUNDS_CHECK_PAD_SIZE * 2));
|
||||
|
||||
if (x_bounds) {
|
||||
/*we're aligning the address twice here but to keep things
|
||||
consistent we want to have the padding come before the stored
|
||||
address so no matter what free function gets called we will
|
||||
attempt to free the correct address*/
|
||||
x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]);
|
||||
x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE,
|
||||
(int)align);
|
||||
/* save the actual malloc address */
|
||||
((size_t *)x)[-1] = (size_t)x_bounds;
|
||||
|
||||
for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int)) {
|
||||
VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int));
|
||||
VPX_MEMCPY_L((unsigned char *)x + size + i,
|
||||
&tempme, sizeof(unsigned int));
|
||||
}
|
||||
} else
|
||||
x = NULL;
|
||||
}
|
||||
#else
|
||||
x = vpx_memalign(align, size);
|
||||
#endif /*TRY_BOUNDS_CHECK*/
|
||||
|
||||
g_alloc_count++;
|
||||
|
||||
vpx_memory_tracker_add((size_t)x, (unsigned int)size, file, line, 1);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void *xvpx_malloc(size_t size, char *file, int line) {
|
||||
return xvpx_memalign(DEFAULT_ALIGNMENT, size, file, line);
|
||||
}
|
||||
|
||||
void *xvpx_calloc(size_t num, size_t size, char *file, int line) {
|
||||
void *x = xvpx_memalign(DEFAULT_ALIGNMENT, num * size, file, line);
|
||||
|
||||
if (x)
|
||||
VPX_MEMSET_L(x, 0, num * size);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void *xvpx_realloc(void *memblk, size_t size, char *file, int line) {
|
||||
struct mem_block *p = NULL;
|
||||
int orig_size = 0,
|
||||
orig_line = 0;
|
||||
char *orig_file = NULL;
|
||||
|
||||
#if TRY_BOUNDS_CHECK
|
||||
unsigned char *x_bounds = memblk ?
|
||||
(unsigned char *)(((size_t *)memblk)[-1]) :
|
||||
NULL;
|
||||
#endif
|
||||
|
||||
void *x;
|
||||
|
||||
if (g_alloc_count == 0) {
|
||||
#if TRY_BOUNDS_CHECK
|
||||
|
||||
if (!vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE))
|
||||
#else
|
||||
if (!vpx_memory_tracker_init(0, 0))
|
||||
#endif
|
||||
{
|
||||
_P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");)
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = vpx_memory_tracker_find((size_t)memblk))) {
|
||||
orig_size = p->size;
|
||||
orig_file = p->file;
|
||||
orig_line = p->line;
|
||||
}
|
||||
|
||||
#if TRY_BOUNDS_CHECK_ON_FREE
|
||||
vpx_memory_tracker_check_integrity(file, line);
|
||||
#endif
|
||||
|
||||
/* have to do this regardless of success, because
|
||||
* the memory that does get realloc'd may change
|
||||
* the bounds values of this block
|
||||
*/
|
||||
vpx_memory_tracker_remove((size_t)memblk);
|
||||
|
||||
#if TRY_BOUNDS_CHECK
|
||||
{
|
||||
int i;
|
||||
unsigned int tempme = BOUNDS_CHECK_VALUE;
|
||||
|
||||
x_bounds = vpx_realloc(memblk, size + (BOUNDS_CHECK_PAD_SIZE * 2));
|
||||
|
||||
if (x_bounds) {
|
||||
x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]);
|
||||
x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE,
|
||||
(int)DEFAULT_ALIGNMENT);
|
||||
/* save the actual malloc address */
|
||||
((size_t *)x)[-1] = (size_t)x_bounds;
|
||||
|
||||
for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int)) {
|
||||
VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int));
|
||||
VPX_MEMCPY_L((unsigned char *)x + size + i,
|
||||
&tempme, sizeof(unsigned int));
|
||||
}
|
||||
} else
|
||||
x = NULL;
|
||||
}
|
||||
#else
|
||||
x = vpx_realloc(memblk, size);
|
||||
#endif /*TRY_BOUNDS_CHECK*/
|
||||
|
||||
if (!memblk) ++g_alloc_count;
|
||||
|
||||
if (x)
|
||||
vpx_memory_tracker_add((size_t)x, (unsigned int)size, file, line, 1);
|
||||
else
|
||||
vpx_memory_tracker_add((size_t)memblk, orig_size, orig_file, orig_line, 1);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void xvpx_free(void *p_address, char *file, int line) {
|
||||
#if TRY_BOUNDS_CHECK
|
||||
unsigned char *p_bounds_address = (unsigned char *)p_address;
|
||||
/*p_bounds_address -= BOUNDS_CHECK_PAD_SIZE;*/
|
||||
#endif
|
||||
|
||||
#if !TRY_BOUNDS_CHECK_ON_FREE
|
||||
(void)file;
|
||||
(void)line;
|
||||
#endif
|
||||
|
||||
if (p_address) {
|
||||
#if TRY_BOUNDS_CHECK_ON_FREE
|
||||
vpx_memory_tracker_check_integrity(file, line);
|
||||
#endif
|
||||
|
||||
/* if the addr isn't found in the list, assume it was allocated via
|
||||
* vpx_ calls not xvpx_, therefore it does not contain any padding
|
||||
*/
|
||||
if (vpx_memory_tracker_remove((size_t)p_address) == -2) {
|
||||
p_bounds_address = p_address;
|
||||
_P(fprintf(stderr, "[vpx_mem][xvpx_free] addr: %p not found in"
|
||||
" list; freed from file:%s"
|
||||
" line:%d\n", p_address, file, line));
|
||||
} else
|
||||
--g_alloc_count;
|
||||
|
||||
#if TRY_BOUNDS_CHECK
|
||||
vpx_free(p_bounds_address);
|
||||
#else
|
||||
vpx_free(p_address);
|
||||
#endif
|
||||
|
||||
if (!g_alloc_count)
|
||||
vpx_memory_tracker_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*CONFIG_MEM_TRACKER*/
|
||||
|
||||
void *vpx_memcpy(void *dest, const void *source, size_t length) {
|
||||
return VPX_MEMCPY_L(dest, source, length);
|
||||
}
|
||||
@ -345,17 +148,6 @@ void *vpx_memmove(void *dest, const void *src, size_t count) {
|
||||
return VPX_MEMMOVE_L(dest, src, count);
|
||||
}
|
||||
|
||||
#if USE_GLOBAL_FUNCTION_POINTERS
|
||||
# if CONFIG_MEM_TRACKER
|
||||
extern int vpx_memory_tracker_set_functions(g_malloc_func g_malloc_l
|
||||
, g_calloc_func g_calloc_l
|
||||
, g_realloc_func g_realloc_l
|
||||
, g_free_func g_free_l
|
||||
, g_memcpy_func g_memcpy_l
|
||||
, g_memset_func g_memset_l
|
||||
, g_memmove_func g_memmove_l);
|
||||
# endif
|
||||
#endif /*USE_GLOBAL_FUNCTION_POINTERS*/
|
||||
int vpx_mem_set_functions(g_malloc_func g_malloc_l
|
||||
, g_calloc_func g_calloc_l
|
||||
, g_realloc_func g_realloc_l
|
||||
@ -378,23 +170,6 @@ int vpx_mem_set_functions(g_malloc_func g_malloc_l
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_MEM_TRACKER
|
||||
{
|
||||
int rv = 0;
|
||||
rv = vpx_memory_tracker_set_functions(g_malloc_l
|
||||
, g_calloc_l
|
||||
, g_realloc_l
|
||||
, g_free_l
|
||||
, g_memcpy_l
|
||||
, g_memset_l
|
||||
, g_memmove_l);
|
||||
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_func->g_malloc = g_malloc_l;
|
||||
g_func->g_calloc = g_calloc_l;
|
||||
g_func->g_realloc = g_realloc_l;
|
||||
|
@ -26,9 +26,6 @@
|
||||
#define VPX_MEM_VERSION_PATCH 5
|
||||
/* end - vpx_mem version info */
|
||||
|
||||
#ifndef VPX_TRACK_MEM_USAGE
|
||||
# define VPX_TRACK_MEM_USAGE 0 /* enable memory tracking/integrity checks */
|
||||
#endif
|
||||
#ifndef REPLACE_BUILTIN_FUNCTIONS
|
||||
# define REPLACE_BUILTIN_FUNCTIONS 0 /* replace builtin functions with their
|
||||
vpx_ equivalents */
|
||||
@ -62,10 +59,6 @@ extern "C" {
|
||||
#endif
|
||||
void *vpx_memmove(void *dest, const void *src, size_t count);
|
||||
|
||||
/* special memory functions */
|
||||
void *vpx_mem_alloc(int id, size_t size, size_t align);
|
||||
void vpx_mem_free(int id, void *mem, size_t size);
|
||||
|
||||
/* Wrappers to standard library functions. */
|
||||
typedef void *(* g_malloc_func)(size_t);
|
||||
typedef void *(* g_calloc_func)(size_t, size_t);
|
||||
@ -103,43 +96,6 @@ extern "C" {
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_MEM_TRACKER
|
||||
#include <stdarg.h>
|
||||
/*from vpx_mem/vpx_mem_tracker.c*/
|
||||
extern void vpx_memory_tracker_dump();
|
||||
extern void vpx_memory_tracker_check_integrity(char *file, unsigned int line);
|
||||
extern int vpx_memory_tracker_set_log_type(int type, char *option);
|
||||
extern int vpx_memory_tracker_set_log_func(void *userdata,
|
||||
void(*logfunc)(void *userdata,
|
||||
const char *fmt, va_list args));
|
||||
# ifndef __VPX_MEM_C__
|
||||
# define vpx_memalign(align, size) xvpx_memalign((align), (size), __FILE__, __LINE__)
|
||||
# define vpx_malloc(size) xvpx_malloc((size), __FILE__, __LINE__)
|
||||
# define vpx_calloc(num, size) xvpx_calloc(num, size, __FILE__, __LINE__)
|
||||
# define vpx_realloc(addr, size) xvpx_realloc(addr, size, __FILE__, __LINE__)
|
||||
# define vpx_free(addr) xvpx_free(addr, __FILE__, __LINE__)
|
||||
# define vpx_memory_tracker_check_integrity() vpx_memory_tracker_check_integrity(__FILE__, __LINE__)
|
||||
# define vpx_mem_alloc(id,size,align) xvpx_mem_alloc(id, size, align, __FILE__, __LINE__)
|
||||
# define vpx_mem_free(id,mem,size) xvpx_mem_free(id, mem, size, __FILE__, __LINE__)
|
||||
# endif
|
||||
|
||||
void *xvpx_memalign(size_t align, size_t size, char *file, int line);
|
||||
void *xvpx_malloc(size_t size, char *file, int line);
|
||||
void *xvpx_calloc(size_t num, size_t size, char *file, int line);
|
||||
void *xvpx_realloc(void *memblk, size_t size, char *file, int line);
|
||||
void xvpx_free(void *memblk, char *file, int line);
|
||||
void *xvpx_mem_alloc(int id, size_t size, size_t align, char *file, int line);
|
||||
void xvpx_mem_free(int id, void *mem, size_t size, char *file, int line);
|
||||
|
||||
#else
|
||||
# ifndef __VPX_MEM_C__
|
||||
# define vpx_memory_tracker_dump()
|
||||
# define vpx_memory_tracker_check_integrity()
|
||||
# define vpx_memory_tracker_set_log_type(t,o) 0
|
||||
# define vpx_memory_tracker_set_log_func(u,f) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef __VPX_MEM_C__
|
||||
# include <string.h>
|
||||
# define vpx_memcpy memcpy
|
||||
|
@ -2,6 +2,3 @@ MEM_SRCS-yes += vpx_mem.mk
|
||||
MEM_SRCS-yes += vpx_mem.c
|
||||
MEM_SRCS-yes += vpx_mem.h
|
||||
MEM_SRCS-yes += include/vpx_mem_intrnl.h
|
||||
|
||||
MEM_SRCS-$(CONFIG_MEM_TRACKER) += vpx_mem_tracker.c
|
||||
MEM_SRCS-$(CONFIG_MEM_TRACKER) += include/vpx_mem_tracker.h
|
||||
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user