/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrMemoryPool.h"

#if GR_DEBUG
    #define VALIDATE this->validate()
#else
    #define VALIDATE
#endif

GrMemoryPool::GrMemoryPool(size_t preallocSize, size_t minAllocSize) {
    GR_DEBUGCODE(fAllocationCnt = 0);

    minAllocSize = GrMax<size_t>(minAllocSize, 1 << 10);
    fMinAllocSize = GrSizeAlignUp(minAllocSize + kPerAllocPad, kAlignment),
    fPreallocSize = GrSizeAlignUp(preallocSize + kPerAllocPad, kAlignment);
    fPreallocSize = GrMax(fPreallocSize, fMinAllocSize);

    fHead = CreateBlock(fPreallocSize);
    fTail = fHead;
    fHead->fNext = NULL;
    fHead->fPrev = NULL;
    VALIDATE;
};

GrMemoryPool::~GrMemoryPool() {
    VALIDATE;
    GrAssert(0 == fAllocationCnt);
    GrAssert(fHead == fTail);
    GrAssert(0 == fHead->fLiveCount);
    DeleteBlock(fHead);
};

void* GrMemoryPool::allocate(size_t size) {
    VALIDATE;
    size = GrSizeAlignUp(size, kAlignment);
    size += kPerAllocPad;
    if (fTail->fFreeSize < size) {
        int blockSize = size;
        blockSize = GrMax<size_t>(blockSize, fMinAllocSize);
        BlockHeader* block = CreateBlock(blockSize);

        block->fPrev = fTail;
        block->fNext = NULL;
        GrAssert(NULL == fTail->fNext);
        fTail->fNext = block;
        fTail = block;
    }
    GrAssert(fTail->fFreeSize >= size);
    intptr_t ptr = fTail->fCurrPtr;
    // We stash a pointer to the block header, just before the allocated space,
    // so that we can decrement the live count on delete in constant time.
    *reinterpret_cast<BlockHeader**>(ptr) = fTail;
    ptr += kPerAllocPad;
    fTail->fPrevPtr = fTail->fCurrPtr;
    fTail->fCurrPtr += size;
    fTail->fFreeSize -= size;
    fTail->fLiveCount += 1;
    GR_DEBUGCODE(++fAllocationCnt);
    VALIDATE;
    return reinterpret_cast<void*>(ptr);
}

void GrMemoryPool::release(void* p) {
    VALIDATE;
    intptr_t ptr = reinterpret_cast<intptr_t>(p) - kPerAllocPad;
    BlockHeader* block = *reinterpret_cast<BlockHeader**>(ptr);
    if (1 == block->fLiveCount) {
        // the head block is special, it is reset rather than deleted
        if (fHead == block) {
            fHead->fCurrPtr = reinterpret_cast<intptr_t>(fHead) +
                                kHeaderSize;
            fHead->fLiveCount = 0;
            fHead->fFreeSize = fPreallocSize;
        } else {
            BlockHeader* prev = block->fPrev;
            BlockHeader* next = block->fNext;
            GrAssert(prev);
            prev->fNext = next;
            if (next) {
                next->fPrev = prev;
            } else {
                GrAssert(fTail == block);
                fTail = prev;
            }
            DeleteBlock(block);
        }
    } else {
        --block->fLiveCount;
        // Trivial reclaim: if we're releasing the most recent allocation, reuse it
        if (block->fPrevPtr == ptr) {
            block->fFreeSize += (block->fCurrPtr - block->fPrevPtr);
            block->fCurrPtr = block->fPrevPtr;
        }
    }
    GR_DEBUGCODE(--fAllocationCnt);
    VALIDATE;
}

GrMemoryPool::BlockHeader* GrMemoryPool::CreateBlock(size_t size) {
    BlockHeader* block =
        reinterpret_cast<BlockHeader*>(GrMalloc(size + kHeaderSize));
    // we assume malloc gives us aligned memory
    GrAssert(!(reinterpret_cast<intptr_t>(block) % kAlignment));
    block->fLiveCount = 0;
    block->fFreeSize = size;
    block->fCurrPtr = reinterpret_cast<intptr_t>(block) + kHeaderSize;
    block->fPrevPtr = 0; // gcc warns on assigning NULL to an intptr_t.
    return block;
}

void GrMemoryPool::DeleteBlock(BlockHeader* block) {
    GrFree(block);
}

void GrMemoryPool::validate() {
    BlockHeader* block = fHead;
    BlockHeader* prev = NULL;
    GrAssert(block);
    int allocCount = 0;
    do {
        allocCount += block->fLiveCount;
        GrAssert(prev == block->fPrev);
        if (NULL != prev) {
            GrAssert(prev->fNext == block);
        }

        intptr_t b = reinterpret_cast<intptr_t>(block);
        size_t ptrOffset = block->fCurrPtr - b;
        size_t totalSize = ptrOffset + block->fFreeSize;
        size_t userSize = totalSize - kHeaderSize;
        intptr_t userStart = b + kHeaderSize;

        GrAssert(!(b % kAlignment));
        GrAssert(!(totalSize % kAlignment));
        GrAssert(!(userSize % kAlignment));
        GrAssert(!(block->fCurrPtr % kAlignment));
        if (fHead != block) {
            GrAssert(block->fLiveCount);
            GrAssert(userSize >= fMinAllocSize);
        } else {
            GrAssert(userSize == fPreallocSize);
        }
        if (!block->fLiveCount) {
            GrAssert(ptrOffset ==  kHeaderSize);
            GrAssert(userStart == block->fCurrPtr);
        } else {
            GrAssert(block == *reinterpret_cast<BlockHeader**>(userStart));
        }
        prev = block;
    } while ((block = block->fNext));
    GrAssert(allocCount == fAllocationCnt);
    GrAssert(prev == fTail);
}

