/*
 * Copyright (C) 2009 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.
 */

#include "rsLocklessFifo.h"
#include "utils/Timers.h"
#include "utils/StopWatch.h"

using namespace android;
using namespace android::renderscript;

LocklessCommandFifo::LocklessCommandFifo() {
}

LocklessCommandFifo::~LocklessCommandFifo() {
    if (!mInShutdown) {
        shutdown();
    }
    free(mBuffer);
}

void LocklessCommandFifo::shutdown() {
    mInShutdown = true;
    mSignalToWorker.set();
}

bool LocklessCommandFifo::init(uint32_t sizeInBytes) {
    // Add room for a buffer reset command
    mBuffer = static_cast<uint8_t *>(malloc(sizeInBytes + 4));
    if (!mBuffer) {
        LOGE("LocklessFifo allocation failure");
        return false;
    }

    if (!mSignalToControl.init() || !mSignalToWorker.init()) {
        LOGE("Signal setup failed");
        free(mBuffer);
        return false;
    }

    mInShutdown = false;
    mSize = sizeInBytes;
    mPut = mBuffer;
    mGet = mBuffer;
    mEnd = mBuffer + (sizeInBytes) - 1;
    //dumpState("init");
    return true;
}

uint32_t LocklessCommandFifo::getFreeSpace() const {
    int32_t freeSpace = 0;
    //dumpState("getFreeSpace");

    if (mPut >= mGet) {
        freeSpace = mEnd - mPut;
    } else {
        freeSpace = mGet - mPut;
    }

    if (freeSpace < 0) {
        freeSpace = 0;
    }
    return freeSpace;
}

bool LocklessCommandFifo::isEmpty() const {
    uint32_t p = android_atomic_acquire_load((int32_t *)&mPut);
    return ((uint8_t *)p) == mGet;
}


void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) {
    // Add space for command header and loop token;
    sizeInBytes += 8;

    //dumpState("reserve");
    if (getFreeSpace() < sizeInBytes) {
        makeSpace(sizeInBytes);
    }

    return mPut + 4;
}

void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) {
    if (mInShutdown) {
        return;
    }
    //dumpState("commit 1");
    reinterpret_cast<uint16_t *>(mPut)[0] = command;
    reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes;
    mPut += ((sizeInBytes + 3) & ~3) + 4;
    //dumpState("commit 2");
    mSignalToWorker.set();
}

void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) {
    if (mInShutdown) {
        return;
    }

    //char buf[1024];
    //sprintf(buf, "RenderScript LocklessCommandFifo::commitSync  %p %i  %i", this, command, sizeInBytes);
    //StopWatch compileTimer(buf);
    commit(command, sizeInBytes);
    flush();
}

void LocklessCommandFifo::flush() {
    //dumpState("flush 1");
    while (mPut != mGet) {
        mSignalToControl.wait();
    }
    //dumpState("flush 2");
}

void LocklessCommandFifo::wait() {
    while (isEmpty() && !mInShutdown) {
        mSignalToControl.set();
        mSignalToWorker.wait();
    }
}

const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) {
    while (1) {
        //dumpState("get");
        wait();
        if (mInShutdown) {
            *command = 0;
            *bytesData = 0;
            return 0;
        }

        *command = reinterpret_cast<const uint16_t *>(mGet)[0];
        *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1];
        if (*command) {
            // non-zero command is valid
            return mGet+4;
        }

        // zero command means reset to beginning.
        mGet = mBuffer;
    }
}

void LocklessCommandFifo::next() {
    uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];

    android_atomic_add(((bytes + 3) & ~3) + 4, (int32_t *)&mGet);
    //mGet += ((bytes + 3) & ~3) + 4;
    if (isEmpty()) {
        mSignalToControl.set();
    }
    //dumpState("next");
}

bool LocklessCommandFifo::makeSpaceNonBlocking(uint32_t bytes) {
    //dumpState("make space non-blocking");
    if ((mPut+bytes) > mEnd) {
        // Need to loop regardless of where get is.
        if ((mGet > mPut) || (mBuffer+4 >= mGet)) {
            return false;
        }

        // Toss in a reset then the normal wait for space will do the rest.
        reinterpret_cast<uint16_t *>(mPut)[0] = 0;
        reinterpret_cast<uint16_t *>(mPut)[1] = 0;
        mPut = mBuffer;
        mSignalToWorker.set();
    }

    // it will fit here so we just need to wait for space.
    if (getFreeSpace() < bytes) {
        return false;
    }

    return true;
}

void LocklessCommandFifo::makeSpace(uint32_t bytes) {
    //dumpState("make space");
    if ((mPut+bytes) > mEnd) {
        // Need to loop regardless of where get is.
        while ((mGet > mPut) || (mBuffer+4 >= mGet)) {
            usleep(100);
        }

        // Toss in a reset then the normal wait for space will do the rest.
        reinterpret_cast<uint16_t *>(mPut)[0] = 0;
        reinterpret_cast<uint16_t *>(mPut)[1] = 0;
        mPut = mBuffer;
        mSignalToWorker.set();
    }

    // it will fit here so we just need to wait for space.
    while (getFreeSpace() < bytes) {
        usleep(100);
    }

}

void LocklessCommandFifo::dumpState(const char *s) const {
    LOGV("%s %p  put %p, get %p,  buf %p,  end %p", s, this, mPut, mGet, mBuffer, mEnd);
}

void LocklessCommandFifo::printDebugData() const {
    dumpState("printing fifo debug");
    const uint32_t *pptr = (const uint32_t *)mGet;
    pptr -= 8 * 4;
    if (mGet < mBuffer) {
        pptr = (const uint32_t *)mBuffer;
    }


    for (int ct=0; ct < 16; ct++) {
        LOGV("fifo %p = 0x%08x  0x%08x  0x%08x  0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
        pptr += 4;
    }

}
