/*
 *  Copyright (c) 2010 The VP8 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
*/

#define NO_MUTEX

#if defined(__uClinux__)
# include <lddk.h>
#endif

#if defined(LINUX) || defined(__uClinux__)
# 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>
#elif defined(NDS_NITRO)
# include <nitro.h>
# include <nitro/os.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 "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


struct memory_tracker
{
    struct mem_block *head,
            * tail;
    int len,
        totalsize;
    unsigned int current_allocated,
             max_allocated;

#if defined(LINUX) || defined(__uClinux__)
    pthread_mutex_t mutex;
#elif defined(WIN32) || defined(_WIN32_WCE)
    HANDLE mutex;
#elif defined(VXWORKS)
    SEM_ID mutex;
#elif defined(NDS_NITRO)
    OSMutex mutex;
#elif defined(NO_MUTEX)
#else
#error "No mutex type defined for this platform!"
#endif

    int padding_size,
        pad_value;
};

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

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 = {0};

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 defined(LINUX) || defined(__uClinux__)
            ret = pthread_mutex_init(&memtrack.mutex,
                                     NULL);            /*mutex attributes (NULL=default)*/
#elif defined(WIN32) || defined(_WIN32_WCE)
            memtrack.mutex = create_mutex(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(NDS_NITRO)
            os_init_mutex(&memtrack.mutex);
            ret = 0;
#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 == 0) && (g_logging.file != 0)) //&& (g_logging.file != stderr) )
        {
#if !defined(NDS_NITRO)
            fclose(g_logging.file);
#endif
            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;
        }

#if !defined(NDS_NITRO)
        else
        {
            if (g_logging.file = fopen((char *)option, "w"))
                ret = 0;
        }

#endif
        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);
        output_debug_string(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] {%s:%d} addr=0x%x, size=%d,"
                                     " file: %s, line: %d c0:0x%x c1:0x%x\n",
                                     index, 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
        {
            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 defined(LINUX) || defined(__uClinux__)
        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);
#elif defined(NDS_NITRO)
        os_lock_mutex(&memtrack.mutex);
        ret = 0;
#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 defined(LINUX) || defined(__uClinux__)
        ret = pthread_mutex_unlock(&memtrack.mutex);
#elif defined(WIN32) || defined(_WIN32_WCE)
        ret = !release_mutex(memtrack.mutex);
#elif defined(VXWORKS)
        ret = sem_give(memtrack.mutex);
#elif defined(NDS_NITRO)
        os_unlock_mutex(&memtrack.mutex);
        ret = 0;
#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
}
