/*
 *  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_ports/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
}
