// Copyright 2019 The Dawn Authors
//
// 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.

#include "dawn/native/BuddyAllocator.h"

#include "dawn/common/Assert.h"
#include "dawn/common/Math.h"

namespace dawn::native {

BuddyAllocator::BuddyAllocator(uint64_t maxSize) : mMaxBlockSize(maxSize) {
    ASSERT(IsPowerOfTwo(maxSize));

    mFreeLists.resize(Log2(mMaxBlockSize) + 1);

    // Insert the level0 free block.
    mRoot = new BuddyBlock(maxSize, /*offset*/ 0);
    mFreeLists[0] = {mRoot};
}

BuddyAllocator::~BuddyAllocator() {
    if (mRoot) {
        DeleteBlock(mRoot);
    }
}

uint64_t BuddyAllocator::ComputeTotalNumOfFreeBlocksForTesting() const {
    return ComputeNumOfFreeBlocks(mRoot);
}

uint64_t BuddyAllocator::ComputeNumOfFreeBlocks(BuddyBlock* block) const {
    if (block->mState == BlockState::Free) {
        return 1;
    } else if (block->mState == BlockState::Split) {
        return ComputeNumOfFreeBlocks(block->split.pLeft) +
               ComputeNumOfFreeBlocks(block->split.pLeft->pBuddy);
    }
    return 0;
}

uint32_t BuddyAllocator::ComputeLevelFromBlockSize(uint64_t blockSize) const {
    // Every level in the buddy system can be indexed by order-n where n = log2(blockSize).
    // However, mFreeList zero-indexed by level.
    // For example, blockSize=4 is Level1 if MAX_BLOCK is 8.
    return Log2(mMaxBlockSize) - Log2(blockSize);
}

uint64_t BuddyAllocator::GetNextFreeAlignedBlock(size_t allocationBlockLevel,
                                                 uint64_t alignment) const {
    ASSERT(IsPowerOfTwo(alignment));
    // The current level is the level that corresponds to the allocation size. The free list may
    // not contain a block at that level until a larger one gets allocated (and splits).
    // Continue to go up the tree until such a larger block exists.
    //
    // Even if the block exists at the level, it cannot be used if it's offset is unaligned.
    // When the alignment is also a power-of-two, we simply use the next free block whose size
    // is greater than or equal to the alignment value.
    //
    //  After one 8-byte allocation:
    //
    //  Level          --------------------------------
    //      0       32 |               S              |
    //                 --------------------------------
    //      1       16 |       S       |       F2     |       S - split
    //                 --------------------------------       F - free
    //      2       8  |   Aa  |   F1  |              |       A - allocated
    //                 --------------------------------
    //
    //  Allocate(size=8, alignment=8) will be satisfied by using F1.
    //  Allocate(size=8, alignment=4) will be satified by using F1.
    //  Allocate(size=8, alignment=16) will be satisified by using F2.
    //
    for (size_t ii = 0; ii <= allocationBlockLevel; ++ii) {
        size_t currLevel = allocationBlockLevel - ii;
        BuddyBlock* freeBlock = mFreeLists[currLevel].head;
        if (freeBlock && (freeBlock->mOffset % alignment == 0)) {
            return currLevel;
        }
    }
    return kInvalidOffset;  // No free block exists at any level.
}

// Inserts existing free block into the free-list.
// Called by allocate upon splitting to insert a child block into a free-list.
// Note: Always insert into the head of the free-list. As when a larger free block at a lower
// level was split, there were no smaller free blocks at a higher level to allocate.
void BuddyAllocator::InsertFreeBlock(BuddyBlock* block, size_t level) {
    ASSERT(block->mState == BlockState::Free);

    // Inserted block is now the front (no prev).
    block->free.pPrev = nullptr;

    // Old head is now the inserted block's next.
    block->free.pNext = mFreeLists[level].head;

    // Block already in HEAD position (ex. right child was inserted first).
    if (mFreeLists[level].head != nullptr) {
        // Old head's previous is the inserted block.
        mFreeLists[level].head->free.pPrev = block;
    }

    mFreeLists[level].head = block;
}

void BuddyAllocator::RemoveFreeBlock(BuddyBlock* block, size_t level) {
    ASSERT(block->mState == BlockState::Free);

    if (mFreeLists[level].head == block) {
        // Block is in HEAD position.
        mFreeLists[level].head = mFreeLists[level].head->free.pNext;
    } else {
        // Block is after HEAD position.
        BuddyBlock* pPrev = block->free.pPrev;
        BuddyBlock* pNext = block->free.pNext;

        ASSERT(pPrev != nullptr);
        ASSERT(pPrev->mState == BlockState::Free);

        pPrev->free.pNext = pNext;

        if (pNext != nullptr) {
            ASSERT(pNext->mState == BlockState::Free);
            pNext->free.pPrev = pPrev;
        }
    }
}

uint64_t BuddyAllocator::Allocate(uint64_t allocationSize, uint64_t alignment) {
    if (allocationSize == 0 || allocationSize > mMaxBlockSize) {
        return kInvalidOffset;
    }

    // Compute the level
    const uint32_t allocationSizeToLevel = ComputeLevelFromBlockSize(allocationSize);

    ASSERT(allocationSizeToLevel < mFreeLists.size());

    uint64_t currBlockLevel = GetNextFreeAlignedBlock(allocationSizeToLevel, alignment);

    // Error when no free blocks exist (allocator is full)
    if (currBlockLevel == kInvalidOffset) {
        return kInvalidOffset;
    }

    // Split free blocks level-by-level.
    // Terminate when the current block level is equal to the computed level of the requested
    // allocation.
    BuddyBlock* currBlock = mFreeLists[currBlockLevel].head;

    for (; currBlockLevel < allocationSizeToLevel; currBlockLevel++) {
        ASSERT(currBlock->mState == BlockState::Free);

        // Remove curr block (about to be split).
        RemoveFreeBlock(currBlock, currBlockLevel);

        // Create two free child blocks (the buddies).
        const uint64_t nextLevelSize = currBlock->mSize / 2;
        BuddyBlock* leftChildBlock = new BuddyBlock(nextLevelSize, currBlock->mOffset);
        BuddyBlock* rightChildBlock =
            new BuddyBlock(nextLevelSize, currBlock->mOffset + nextLevelSize);

        // Remember the parent to merge these back upon de-allocation.
        rightChildBlock->pParent = currBlock;
        leftChildBlock->pParent = currBlock;

        // Make them buddies.
        leftChildBlock->pBuddy = rightChildBlock;
        rightChildBlock->pBuddy = leftChildBlock;

        // Insert the children back into the free list into the next level.
        // The free list does not require a specific order. However, an order is specified as
        // it's ideal to allocate lower addresses first by having the leftmost child in HEAD.
        InsertFreeBlock(rightChildBlock, currBlockLevel + 1);
        InsertFreeBlock(leftChildBlock, currBlockLevel + 1);

        // Curr block is now split.
        currBlock->mState = BlockState::Split;
        currBlock->split.pLeft = leftChildBlock;

        // Decend down into the next level.
        currBlock = leftChildBlock;
    }

    // Remove curr block from free-list (now allocated).
    RemoveFreeBlock(currBlock, currBlockLevel);
    currBlock->mState = BlockState::Allocated;

    return currBlock->mOffset;
}

void BuddyAllocator::Deallocate(uint64_t offset) {
    BuddyBlock* curr = mRoot;

    // TODO(crbug.com/dawn/827): Optimize de-allocation.
    // Passing allocationSize directly will avoid the following level-by-level search;
    // however, it requires the size information to be stored outside the allocator.

    // Search for the free block node that corresponds to the block offset.
    size_t currBlockLevel = 0;
    while (curr->mState == BlockState::Split) {
        if (offset < curr->split.pLeft->pBuddy->mOffset) {
            curr = curr->split.pLeft;
        } else {
            curr = curr->split.pLeft->pBuddy;
        }

        currBlockLevel++;
    }

    ASSERT(curr->mState == BlockState::Allocated);

    // Ensure the block is at the correct level
    ASSERT(currBlockLevel == ComputeLevelFromBlockSize(curr->mSize));

    // Mark curr free so we can merge.
    curr->mState = BlockState::Free;

    // Merge the buddies (LevelN-to-Level0).
    while (currBlockLevel > 0 && curr->pBuddy->mState == BlockState::Free) {
        // Remove the buddy.
        RemoveFreeBlock(curr->pBuddy, currBlockLevel);

        BuddyBlock* parent = curr->pParent;

        // The buddies were inserted in a specific order but
        // could be deleted in any order.
        DeleteBlock(curr->pBuddy);
        DeleteBlock(curr);

        // Parent is now free.
        parent->mState = BlockState::Free;

        // Ascend up to the next level (parent block).
        curr = parent;
        currBlockLevel--;
    }

    InsertFreeBlock(curr, currBlockLevel);
}

// Helper which deletes a block in the tree recursively (post-order).
void BuddyAllocator::DeleteBlock(BuddyBlock* block) {
    ASSERT(block != nullptr);

    if (block->mState == BlockState::Split) {
        // Delete the pair in same order we inserted.
        DeleteBlock(block->split.pLeft->pBuddy);
        DeleteBlock(block->split.pLeft);
    }
    delete block;
}

}  // namespace dawn::native
