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

#include "utils/LinearAllocator.h"

#include <stdlib.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)512) // 512b
#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_RATIO (0.5f)

#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()
#define RM_ALLOCATION()
#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 pages allocated: %zu", s_totalAllocations);
    }
}

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

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

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

namespace android {
namespace uirenderer {

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(INITIAL_PAGE_SIZE * MAX_WASTE_RATIO)
    , mNext(0)
    , mCurrentPage(0)
    , mPages(0)
    , mTotalAllocated(0)
    , mWastedSpace(0)
    , mPageCount(0)
    , mDedicatedPageCount(0) {}

LinearAllocator::~LinearAllocator(void) {
    while (mDtorList) {
        auto node = mDtorList;
        mDtorList = node->next;
        node->dtor(node->addr);
    }
    Page* p = mPages;
    while (p) {
        Page* next = p->next();
        p->~Page();
        free(p);
        RM_ALLOCATION();
        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);
        mMaxAllocSize = mPageSize * MAX_WASTE_RATIO;
        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::allocImpl(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::addToDestructionList(Destructor dtor, void* addr) {
    static_assert(std::is_standard_layout<DestructorNode>::value,
                  "DestructorNode must have standard layout");
    static_assert(std::is_trivially_destructible<DestructorNode>::value,
                  "DestructorNode must be trivially destructable");
    auto node = new (allocImpl(sizeof(DestructorNode))) DestructorNode();
    node->dtor = dtor;
    node->addr = addr;
    node->next = mDtorList;
    mDtorList = node;
}

void LinearAllocator::runDestructorFor(void* addr) {
    auto node = mDtorList;
    DestructorNode* previous = nullptr;
    while (node) {
        if (node->addr == addr) {
            if (previous) {
                previous->next = node->next;
            } else {
                mDtorList = node->next;
            }
            node->dtor(node->addr);
            rewindIfLastAlloc(node, sizeof(DestructorNode));
            break;
        }
        previous = node;
        node = node->next;
    }
}

void LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) {
    // First run the destructor as running the destructor will
    // also rewind for the DestructorNode allocation which will
    // have been allocated after this void* if it has a destructor
    runDestructorFor(ptr);
    // Don't bother rewinding across pages
    allocSize = ALIGN(allocSize);
    if (ptr >= start(mCurrentPage) && ptr < end(mCurrentPage)
            && ptr == ((char*)mNext - allocSize)) {
        mWastedSpace += allocSize;
        mNext = ptr;
    }
}

LinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) {
    pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page));
    ADD_ALLOCATION();
    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 uirenderer
}; // namespace android
