/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "MemoryDealer"

#include <utils/MemoryDealer.h>

#include <utils/Log.h>
#include <utils/IPCThreadState.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
#include <utils/MemoryBase.h>

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/file.h>

namespace android {


// ----------------------------------------------------------------------------

class SimpleMemory : public MemoryBase {
public:
    SimpleMemory(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
    virtual ~SimpleMemory();
};


// ----------------------------------------------------------------------------

MemoryDealer::Allocation::Allocation(
        const sp<MemoryDealer>& dealer, ssize_t offset, size_t size,
        const sp<IMemory>& memory)
    : mDealer(dealer), mOffset(offset), mSize(size), mMemory(memory) 
{
}

MemoryDealer::Allocation::~Allocation()
{
    if (mSize) {
        /* NOTE: it's VERY important to not free allocations of size 0 because
         * they're special as they don't have any record in the allocator
         * and could alias some real allocation (their offset is zero). */
        mDealer->deallocate(mOffset);
    }
}

sp<IMemoryHeap> MemoryDealer::Allocation::getMemory(
    ssize_t* offset, size_t* size) const
{
    return mMemory->getMemory(offset, size);
}

// ----------------------------------------------------------------------------

MemoryDealer::MemoryDealer(size_t size, uint32_t flags, const char* name)
    : mHeap(new SharedHeap(size, flags, name)),
    mAllocator(new SimpleBestFitAllocator(size))
{    
}

MemoryDealer::MemoryDealer(const sp<HeapInterface>& heap)
    : mHeap(heap),
    mAllocator(new SimpleBestFitAllocator(heap->virtualSize()))
{
}

MemoryDealer::MemoryDealer( const sp<HeapInterface>& heap,
        const sp<AllocatorInterface>& allocator)
    : mHeap(heap), mAllocator(allocator)
{
}

MemoryDealer::~MemoryDealer()
{
}

sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags)
{
    sp<IMemory> memory;
    const ssize_t offset = allocator()->allocate(size, flags);
    if (offset >= 0) {
        sp<IMemory> new_memory = heap()->mapMemory(offset, size);
        if (new_memory != 0) {
            memory = new Allocation(this, offset, size, new_memory);
        } else {
            LOGE("couldn't map [%8x, %d]", offset, size);
            if (size) {
                /* NOTE: it's VERY important to not free allocations of size 0
                 * because they're special as they don't have any record in the 
                 * allocator and could alias some real allocation 
                 * (their offset is zero). */
                allocator()->deallocate(offset);
            }
        }        
    }
    return memory;
}

void MemoryDealer::deallocate(size_t offset)
{
    allocator()->deallocate(offset);
}

void MemoryDealer::dump(const char* what, uint32_t flags) const
{
    allocator()->dump(what, flags);
}

const sp<HeapInterface>& MemoryDealer::heap() const {
    return mHeap;
}

const sp<AllocatorInterface>& MemoryDealer::allocator() const {
    return mAllocator;
}

// ----------------------------------------------------------------------------

// align all the memory blocks on a cache-line boundary
const int SimpleBestFitAllocator::kMemoryAlign = 32;

SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
{
    size_t pagesize = getpagesize();
    mHeapSize = ((size + pagesize-1) & ~(pagesize-1));

    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
    mList.insertHead(node);
}

SimpleBestFitAllocator::~SimpleBestFitAllocator()
{
    while(!mList.isEmpty()) {
        delete mList.remove(mList.head());
    }
}

size_t SimpleBestFitAllocator::size() const
{
    return mHeapSize;
}

size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
{
    Mutex::Autolock _l(mLock);
    ssize_t offset = alloc(size, flags);
    return offset;
}

status_t SimpleBestFitAllocator::deallocate(size_t offset)
{
    Mutex::Autolock _l(mLock);
    chunk_t const * const freed = dealloc(offset);
    if (freed) {
        return NO_ERROR;
    }
    return NAME_NOT_FOUND;
}

ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
{
    if (size == 0) {
        return 0;
    }
    size = (size + kMemoryAlign-1) / kMemoryAlign;
    chunk_t* free_chunk = 0;
    chunk_t* cur = mList.head();

    size_t pagesize = getpagesize();
    while (cur) {
        int extra = 0;
        if (flags & PAGE_ALIGNED)
            extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;

        // best fit
        if (cur->free && (cur->size >= (size+extra))) {
            if ((!free_chunk) || (cur->size < free_chunk->size)) {
                free_chunk = cur;
            }
            if (cur->size == size) {
                break;
            }
        }
        cur = cur->next;
    }

    if (free_chunk) {
        const size_t free_size = free_chunk->size;
        free_chunk->free = 0;
        free_chunk->size = size;
        if (free_size > size) {
            int extra = 0;
            if (flags & PAGE_ALIGNED)
                extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
            if (extra) {
                chunk_t* split = new chunk_t(free_chunk->start, extra);
                free_chunk->start += extra;
                mList.insertBefore(free_chunk, split);
            }

            LOGE_IF((flags&PAGE_ALIGNED) && 
                    ((free_chunk->start*kMemoryAlign)&(pagesize-1)),
                    "PAGE_ALIGNED requested, but page is not aligned!!!");

            const ssize_t tail_free = free_size - (size+extra);
            if (tail_free > 0) {
                chunk_t* split = new chunk_t(
                        free_chunk->start + free_chunk->size, tail_free);
                mList.insertAfter(free_chunk, split);
            }
        }
        return (free_chunk->start)*kMemoryAlign;
    }
    return NO_MEMORY;
}

SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
{
    start = start / kMemoryAlign;
    chunk_t* cur = mList.head();
    while (cur) {
        if (cur->start == start) {
            LOG_FATAL_IF(cur->free,
                "block at offset 0x%08lX of size 0x%08lX already freed",
                cur->start*kMemoryAlign, cur->size*kMemoryAlign);

            // merge freed blocks together
            chunk_t* freed = cur;
            cur->free = 1;
            do {
                chunk_t* const p = cur->prev;
                chunk_t* const n = cur->next;
                if (p && (p->free || !cur->size)) {
                    freed = p;
                    p->size += cur->size;
                    mList.remove(cur);
                    delete cur;
                }
                cur = n;
            } while (cur && cur->free);

            #ifndef NDEBUG
                if (!freed->free) {
                    dump_l("dealloc (!freed->free)");
                }
            #endif
            LOG_FATAL_IF(!freed->free,
                "freed block at offset 0x%08lX of size 0x%08lX is not free!",
                freed->start * kMemoryAlign, freed->size * kMemoryAlign);

            return freed;
        }
        cur = cur->next;
    }
    return 0;
}

void SimpleBestFitAllocator::dump(const char* what, uint32_t flags) const
{
    Mutex::Autolock _l(mLock);
    dump_l(what, flags);
}

void SimpleBestFitAllocator::dump_l(const char* what, uint32_t flags) const
{
    String8 result;
    dump_l(result, what, flags);
    LOGD("%s", result.string());
}

void SimpleBestFitAllocator::dump(String8& result,
        const char* what, uint32_t flags) const
{
    Mutex::Autolock _l(mLock);
    dump_l(result, what, flags);
}

void SimpleBestFitAllocator::dump_l(String8& result,
        const char* what, uint32_t flags) const
{
    size_t size = 0;
    int32_t i = 0;
    chunk_t const* cur = mList.head();
    
    const size_t SIZE = 256;
    char buffer[SIZE];
    snprintf(buffer, SIZE, "  %s (%p, size=%u)\n",
            what, this, (unsigned int)mHeapSize);
    
    result.append(buffer);
            
    while (cur) {
        const char* errs[] = {"", "| link bogus NP",
                            "| link bogus PN", "| link bogus NP+PN" };
        int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
        int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;

        snprintf(buffer, SIZE, "  %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
            i, int(cur), int(cur->start*kMemoryAlign),
            int(cur->size*kMemoryAlign),
                    int(cur->free) ? "F" : "A",
                    errs[np|pn]);
        
        result.append(buffer);

        if (!cur->free)
            size += cur->size*kMemoryAlign;

        i++;
        cur = cur->next;
    }
    snprintf(buffer, SIZE, "  size allocated: %u (%u KB)\n", int(size), int(size/1024));
    result.append(buffer);
}
        
// ----------------------------------------------------------------------------


SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
    : MemoryHeapBase(size, flags, name)
{
}

SharedHeap::~SharedHeap()
{
}

sp<IMemory> SharedHeap::mapMemory(size_t offset, size_t size)
{
    return new SimpleMemory(this, offset, size);
}
 

SimpleMemory::SimpleMemory(const sp<IMemoryHeap>& heap,
        ssize_t offset, size_t size)
    : MemoryBase(heap, offset, size)
{
#ifndef NDEBUG
    void* const start_ptr = (void*)(intptr_t(heap->base()) + offset);
    memset(start_ptr, 0xda, size);
#endif
}

SimpleMemory::~SimpleMemory()
{
    size_t freedOffset = getOffset();
    size_t freedSize   = getSize();

    // keep the size to unmap in excess
    size_t pagesize = getpagesize();
    size_t start = freedOffset;
    size_t end = start + freedSize;
    start &= ~(pagesize-1);
    end = (end + pagesize-1) & ~(pagesize-1);

    // give back to the kernel the pages we don't need
    size_t free_start = freedOffset;
    size_t free_end = free_start + freedSize;
    if (start < free_start)
        start = free_start;
    if (end > free_end)
        end = free_end;
    start = (start + pagesize-1) & ~(pagesize-1);
    end &= ~(pagesize-1);    

    if (start < end) {
        void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
        size_t size = end-start;

#ifndef NDEBUG
        memset(start_ptr, 0xdf, size);
#endif

        // MADV_REMOVE is not defined on Dapper based Goobuntu 
#ifdef MADV_REMOVE 
        if (size) {
            int err = madvise(start_ptr, size, MADV_REMOVE);
            LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
                    start_ptr, size, err<0 ? strerror(errno) : "Ok");
        }
#endif
    }
}

}; // namespace android
