/*
 * Copyright 2012, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define LOG_TAG "LinearAllocator"
#define LOG_NDEBUG 1

#include <stdlib.h>
#include <utils/LinearAllocator.h>
#include <utils/Log.h>


// The ideal size of a page allocation (these need to be multiples of 8)
#define INITIAL_PAGE_SIZE ((size_t)4096) // 4kb
#define MAX_PAGE_SIZE ((size_t)131072) // 128kb

// The maximum amount of wasted space we can have per page
// Allocations exceeding this will have their own dedicated page
// If this is too low, we will malloc too much
// Too high, and we may waste too much space
// Must be smaller than INITIAL_PAGE_SIZE
#define MAX_WASTE_SIZE ((size_t)1024)

#if ALIGN_DOUBLE
#define ALIGN_SZ (sizeof(double))
#else
#define ALIGN_SZ (sizeof(int))
#endif

#define ALIGN(x) ((x + ALIGN_SZ - 1 ) & ~(ALIGN_SZ - 1))
#define ALIGN_PTR(p) ((void*)(ALIGN((size_t)p)))

#if LOG_NDEBUG
#define ADD_ALLOCATION(size)
#define RM_ALLOCATION(size)
#else
#include <utils/Thread.h>
#include <utils/Timers.h>
static size_t s_totalAllocations = 0;
static nsecs_t s_nextLog = 0;
static android::Mutex s_mutex;

static void _logUsageLocked() {
    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    if (now > s_nextLog) {
        s_nextLog = now + milliseconds_to_nanoseconds(10);
        ALOGV("Total memory usage: %zu kb", s_totalAllocations / 1024);
    }
}

static void _addAllocation(size_t size) {
    android::AutoMutex lock(s_mutex);
    s_totalAllocations += size;
    _logUsageLocked();
}

#define ADD_ALLOCATION(size) _addAllocation(size);
#define RM_ALLOCATION(size) _addAllocation(-size);
#endif

#define min(x,y) (((x) < (y)) ? (x) : (y))

namespace android {

class LinearAllocator::Page {
public:
    Page* next() { return mNextPage; }
    void setNext(Page* next) { mNextPage = next; }

    Page()
        : mNextPage(0)
    {}

    void* operator new(size_t size, void* buf) { return buf; }

    void* start() {
        return (void*) (((size_t)this) + sizeof(Page));
    }

    void* end(int pageSize) {
        return (void*) (((size_t)start()) + pageSize);
    }

private:
    Page(const Page& other) {}
    Page* mNextPage;
};

LinearAllocator::LinearAllocator()
    : mPageSize(INITIAL_PAGE_SIZE)
    , mMaxAllocSize(MAX_WASTE_SIZE)
    , mNext(0)
    , mCurrentPage(0)
    , mPages(0)
    , mTotalAllocated(0)
    , mWastedSpace(0)
    , mPageCount(0)
    , mDedicatedPageCount(0) {}

LinearAllocator::~LinearAllocator(void) {
    Page* p = mPages;
    while (p) {
        Page* next = p->next();
        p->~Page();
        free(p);
        RM_ALLOCATION(mPageSize);
        p = next;
    }
}

void* LinearAllocator::start(Page* p) {
    return ALIGN_PTR(((size_t*)p) + sizeof(Page));
}

void* LinearAllocator::end(Page* p) {
    return ((char*)p) + mPageSize;
}

bool LinearAllocator::fitsInCurrentPage(size_t size) {
    return mNext && ((char*)mNext + size) <= end(mCurrentPage);
}

void LinearAllocator::ensureNext(size_t size) {
    if (fitsInCurrentPage(size)) return;

    if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) {
        mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2);
        mPageSize = ALIGN(mPageSize);
    }
    mWastedSpace += mPageSize;
    Page* p = newPage(mPageSize);
    if (mCurrentPage) {
        mCurrentPage->setNext(p);
    }
    mCurrentPage = p;
    if (!mPages) {
        mPages = mCurrentPage;
    }
    mNext = start(mCurrentPage);
}

void* LinearAllocator::alloc(size_t size) {
    size = ALIGN(size);
    if (size > mMaxAllocSize && !fitsInCurrentPage(size)) {
        ALOGV("Exceeded max size %zu > %zu", size, mMaxAllocSize);
        // Allocation is too large, create a dedicated page for the allocation
        Page* page = newPage(size);
        mDedicatedPageCount++;
        page->setNext(mPages);
        mPages = page;
        if (!mCurrentPage)
            mCurrentPage = mPages;
        return start(page);
    }
    ensureNext(size);
    void* ptr = mNext;
    mNext = ((char*)mNext) + size;
    mWastedSpace -= size;
    return ptr;
}

void LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) {
    // Don't bother rewinding across pages
    allocSize = ALIGN(allocSize);
    if (ptr >= start(mCurrentPage) && ptr < end(mCurrentPage)
            && ptr == ((char*)mNext - allocSize)) {
        mTotalAllocated -= allocSize;
        mWastedSpace += allocSize;
        mNext = ptr;
    }
}

LinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) {
    pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page));
    ADD_ALLOCATION(pageSize);
    mTotalAllocated += pageSize;
    mPageCount++;
    void* buf = malloc(pageSize);
    return new (buf) Page();
}

static const char* toSize(size_t value, float& result) {
    if (value < 2000) {
        result = value;
        return "B";
    }
    if (value < 2000000) {
        result = value / 1024.0f;
        return "KB";
    }
    result = value / 1048576.0f;
    return "MB";
}

void LinearAllocator::dumpMemoryStats(const char* prefix) {
    float prettySize;
    const char* prettySuffix;
    prettySuffix = toSize(mTotalAllocated, prettySize);
    ALOGD("%sTotal allocated: %.2f%s", prefix, prettySize, prettySuffix);
    prettySuffix = toSize(mWastedSpace, prettySize);
    ALOGD("%sWasted space: %.2f%s (%.1f%%)", prefix, prettySize, prettySuffix,
          (float) mWastedSpace / (float) mTotalAllocated * 100.0f);
    ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount);
}

}; // namespace android
