/*
 * default memory allocator for libavutil
 * Copyright (c) 2002 Fabrice Bellard
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file libavutil/mem.c
 * default memory allocator for libavutil
 */

#include "config.h"
#include "log.h"

#include <limits.h>
#include <stdlib.h>
#include <string.h>
#if HAVE_MALLOC_H
#include <malloc.h>
#endif

#include "mem.h"

/* here we can use OS-dependent allocation functions */
#undef free
#undef malloc
#undef realloc

/* You can redefine av_malloc and av_free in your project to use your
   memory allocator. You do not need to suppress this file because the
   linker will do it automatically. */

void *av_malloc(unsigned int size)
{
    void *ptr = NULL;
#if CONFIG_MEMALIGN_HACK
    long diff;
#endif

    /* let's disallow possible ambiguous cases */
    if(size > (INT_MAX-16) )
        return NULL;

#ifdef EM8622
    if(size > 8*1024*1024)
        return NULL;
#endif

#if CONFIG_MEMALIGN_HACK
    ptr = malloc(size+16);
    if(!ptr)
        return ptr;
    diff= ((-(long)ptr - 1)&15) + 1;
    ptr = (char*)ptr + diff;
    ((char*)ptr)[-1]= diff;
#elif HAVE_POSIX_MEMALIGN
    if (posix_memalign(&ptr,16,size))
        ptr = NULL;
#elif HAVE_MEMALIGN
    ptr = memalign(16,size);
    /* Why 64?
       Indeed, we should align it:
         on 4 for 386
         on 16 for 486
         on 32 for 586, PPro - K6-III
         on 64 for K7 (maybe for P3 too).
       Because L1 and L2 caches are aligned on those values.
       But I don't want to code such logic here!
     */
     /* Why 16?
        Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
        it will just trigger an exception and the unaligned load will be done in the
        exception handler or it will just segfault (SSE2 on P4).
        Why not larger? Because I did not see a difference in benchmarks ...
     */
     /* benchmarks with P3
        memalign(64)+1          3071,3051,3032
        memalign(64)+2          3051,3032,3041
        memalign(64)+4          2911,2896,2915
        memalign(64)+8          2545,2554,2550
        memalign(64)+16         2543,2572,2563
        memalign(64)+32         2546,2545,2571
        memalign(64)+64         2570,2533,2558

        BTW, malloc seems to do 8-byte alignment by default here.
     */
#else
    ptr = malloc(size);
#endif
    return ptr;
}

#ifdef EM8622UNCACHED

typedef void* mspace;
extern mspace create_mspace_with_base(void* base, size_t capacity, int locked);
extern void* mspace_malloc(mspace msp, size_t bytes);
extern void mspace_free(mspace msp, void* mem);
extern size_t mspace_footprint(mspace msp);
extern void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);

#define UNCACHEDCOUNT 3
// 1 page less than 2 megs
#define UNCACHEDSIZE 2*1024*1022
static unsigned int uncachedmembuf[UNCACHEDCOUNT] = {0,};
static mspace uncachedmem[UNCACHEDCOUNT] = {NULL, };
#undef fprintf
#undef fflush
#endif

#undef fprintf
#undef fflush

void *av_realloc(void *ptr, unsigned int size)
{
    int i;
#if CONFIG_MEMALIGN_HACK
    int diff;
#endif

    /* let's disallow possible ambiguous cases */
    if(size > (INT_MAX-16) )
        return NULL;

	/* catch cases of runaway memor allocation */
	if(size > (16*1024*1024))	// warning if > 16 megs
		fprintf(stderr, "WARNING: Large av_realloc, size=%d\n", size);
#ifdef EM8622
    if(size > 8*1024*1024)
        return NULL;
#endif
#ifdef EM8622UNCACHED
    
    for(i=0;i<UNCACHEDCOUNT;i++)
    {
        if (ptr && ((unsigned int)ptr)>= uncachedmembuf[i] && ((unsigned int)ptr) < (uncachedmembuf[i]+UNCACHEDSIZE))
        {
            fprintf(stderr, "realloc in uncached? %X\n",(unsigned int)ptr);
            return NULL;
        }
    }
#endif
#if CONFIG_MEMALIGN_HACK
    //FIXME this isn't aligned correctly, though it probably isn't needed
    if(!ptr) return av_malloc(size);
    diff= ((char*)ptr)[-1];
    ptr= realloc((char*)ptr - diff, size + diff);
    if(ptr) ptr = (char*)ptr + diff;
    return ptr;
#else
    return realloc(ptr, size);
#endif
}

#ifdef EM8622UNCACHED

static mspace initUncached(int size, int index)
{
    void *buffer = av_malloc(size);
    mspace m1;
    unsigned char *tmpbuf = av_malloc(16384);
    int i;
    fprintf(stderr, "Creating mspace at %X\n",(unsigned int)buffer);
    buffer = (void *) (((unsigned int)buffer)&0x7FFFFFFF);
    // Clean cache
    for(i=0;i<16384;i++) tmpbuf[i]=i;
    uncachedmembuf[index] = (unsigned int)buffer;
    m1 = create_mspace_with_base(buffer, size, 0);
    av_free(tmpbuf);
    return m1;
}

void *av_mallocUncached(unsigned int size)
{
    int i;
    static int initialized=0;
    void *outptr;
    if(!initialized)
    {
        for(i=0;i<UNCACHEDCOUNT;i++)
        {
            uncachedmem[i] = initUncached(UNCACHEDSIZE, i);
        }
        initialized=1;
    }
    for(i=0;i<UNCACHEDCOUNT;i++)
    {
        outptr = mspace_memalign(uncachedmem[i], 16, size);
        if(outptr!=NULL) return outptr;
    }
//    fprintf(stderr, "Allocating %d bytes uncached ret %X\n", size, (unsigned int)outptr);
    return outptr;
}

#endif

void av_free(void *ptr)
{
    /* XXX: this test should not be needed on most libcs */
#ifdef EM8622UNCACHED
    int i;
    for(i=0;i<UNCACHEDCOUNT;i++)
    {
        if (ptr && ((unsigned int)ptr)>= uncachedmembuf[i] && ((unsigned int)ptr) < (uncachedmembuf[i]+UNCACHEDSIZE))
        {
//            fprintf(stderr, "Freeing %X\n", (unsigned int)ptr);
            mspace_free(uncachedmem[i], ptr);
            return;
        }
    }
#endif
    if (ptr)
#if CONFIG_MEMALIGN_HACK
        free((char*)ptr - ((char*)ptr)[-1]);
#else
        free(ptr);
#endif
}

void av_freep(void *arg)
{
    void **ptr= (void**)arg;
    av_free(*ptr);
    *ptr = NULL;
}

void *av_mallocz(unsigned int size)
{
    void *ptr = av_malloc(size);
    if (ptr)
        memset(ptr, 0, size);
    return ptr;
}

char *av_strdup(const char *s)
{
    char *ptr= NULL;
    if(s){
        int len = strlen(s) + 1;
        ptr = av_malloc(len);
        if (ptr)
            memcpy(ptr, s, len);
    }
    return ptr;
}

#ifdef EM8622UNCACHED
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif

// We implement this to use kernel copy
void *av_memcpy(void *dest, const void *src, unsigned int size)
{
#ifdef EM8622UNCACHED
    static int devmemfd=-1;
    static unsigned long long bytescopied=0;

    if(devmemfd<0)
    {
        devmemfd=open("/dev/mem",O_RDWR);
    }
    #undef fprintf
   /* fprintf(stderr, "av_memcpy: pread %X %X %X\n",(unsigned int)dest, (unsigned int)src, size);
    fflush(stderr);
    usleep(1000);*/
    if(((((unsigned int)dest)|((unsigned int)src))&0x80000000)==0 && size > 256)
    {
        lseek(devmemfd, ((unsigned int)src), SEEK_SET);
        if(read(devmemfd, dest, size)!=size)
        {
            fprintf(stderr, "av_memcpy: pread %X %X %X failed\n",(unsigned int)dest, (unsigned int)src, size);
        }
        bytescopied+=size;
        return dest;
    }
    else
#endif
    {
        return memcpy(dest,src,size);
    }
}
