diff options
Diffstat (limited to 'libs/rs/rsLocklessFifo.cpp')
-rw-r--r-- | libs/rs/rsLocklessFifo.cpp | 161 |
1 files changed, 52 insertions, 109 deletions
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp index c796520..e87525e 100644 --- a/libs/rs/rsLocklessFifo.cpp +++ b/libs/rs/rsLocklessFifo.cpp @@ -15,30 +15,28 @@ */ #include "rsLocklessFifo.h" +#include "utils/Timers.h" +#include "utils/StopWatch.h" using namespace android; +using namespace android::renderscript; - -LocklessCommandFifo::LocklessCommandFifo() -{ +LocklessCommandFifo::LocklessCommandFifo() { } -LocklessCommandFifo::~LocklessCommandFifo() -{ +LocklessCommandFifo::~LocklessCommandFifo() { if (!mInShutdown) { shutdown(); } free(mBuffer); } -void LocklessCommandFifo::shutdown() -{ +void LocklessCommandFifo::shutdown() { mInShutdown = true; mSignalToWorker.set(); } -bool LocklessCommandFifo::init(uint32_t sizeInBytes) -{ +bool LocklessCommandFifo::init(uint32_t sizeInBytes) { // Add room for a buffer reset command mBuffer = static_cast<uint8_t *>(malloc(sizeInBytes + 4)); if (!mBuffer) { @@ -61,8 +59,7 @@ bool LocklessCommandFifo::init(uint32_t sizeInBytes) return true; } -uint32_t LocklessCommandFifo::getFreeSpace() const -{ +uint32_t LocklessCommandFifo::getFreeSpace() const { int32_t freeSpace = 0; //dumpState("getFreeSpace"); @@ -78,14 +75,12 @@ uint32_t LocklessCommandFifo::getFreeSpace() const return freeSpace; } -bool LocklessCommandFifo::isEmpty() const -{ +bool LocklessCommandFifo::isEmpty() const { return mPut == mGet; } -void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) -{ +void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) { // Add space for command header and loop token; sizeInBytes += 8; @@ -97,8 +92,7 @@ void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) return mPut + 4; } -void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) -{ +void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) { if (mInShutdown) { return; } @@ -110,33 +104,37 @@ void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) mSignalToWorker.set(); } -void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) -{ +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() -{ +void LocklessCommandFifo::flush() { //dumpState("flush 1"); - while(mPut != mGet) { + while (mPut != mGet) { mSignalToControl.wait(); } //dumpState("flush 2"); } -const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) -{ - while(1) { - //dumpState("get"); - while(isEmpty() && !mInShutdown) { - mSignalToControl.set(); - mSignalToWorker.wait(); - } +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; @@ -155,8 +153,7 @@ const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) } } -void LocklessCommandFifo::next() -{ +void LocklessCommandFifo::next() { uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1]; mGet += ((bytes + 3) & ~3) + 4; if (isEmpty()) { @@ -165,106 +162,52 @@ void LocklessCommandFifo::next() //dumpState("next"); } -void LocklessCommandFifo::makeSpace(uint32_t bytes) -{ - //dumpState("make space"); +bool LocklessCommandFifo::makeSpaceNonBlocking(uint32_t bytes) { + //dumpState("make space non-blocking"); if ((mPut+bytes) > mEnd) { // Need to loop regardless of where get is. - while((mGet > mPut) && (mBuffer+4 >= mGet)) { - usleep(100); + 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. - while(getFreeSpace() < bytes) { - usleep(100); - } - -} - -void LocklessCommandFifo::dumpState(const char *s) const -{ - LOGV("%s put %p, get %p, buf %p, end %p", s, mPut, mGet, mBuffer, mEnd); -} - -LocklessCommandFifo::Signal::Signal() -{ - mSet = true; -} - -LocklessCommandFifo::Signal::~Signal() -{ - pthread_mutex_destroy(&mMutex); - pthread_cond_destroy(&mCondition); -} - -bool LocklessCommandFifo::Signal::init() -{ - int status = pthread_mutex_init(&mMutex, NULL); - if (status) { - LOGE("LocklessFifo mutex init failure"); - return false; - } - - status = pthread_cond_init(&mCondition, NULL); - if (status) { - LOGE("LocklessFifo condition init failure"); - pthread_mutex_destroy(&mMutex); + if (getFreeSpace() < bytes) { return false; } return true; } -void LocklessCommandFifo::Signal::set() -{ - int status; +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); + } - status = pthread_mutex_lock(&mMutex); - if (status) { - LOGE("LocklessCommandFifo: error %i locking for set condition.", status); - return; + // 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(); } - mSet = true; - - status = pthread_cond_signal(&mCondition); - if (status) { - LOGE("LocklessCommandFifo: error %i on set condition.", status); + // it will fit here so we just need to wait for space. + while (getFreeSpace() < bytes) { + usleep(100); } - status = pthread_mutex_unlock(&mMutex); - if (status) { - LOGE("LocklessCommandFifo: error %i unlocking for set condition.", status); - } } -void LocklessCommandFifo::Signal::wait() -{ - int status; - - status = pthread_mutex_lock(&mMutex); - if (status) { - LOGE("LocklessCommandFifo: error %i locking for condition.", status); - return; - } - - if (!mSet) { - status = pthread_cond_wait(&mCondition, &mMutex); - if (status) { - LOGE("LocklessCommandFifo: error %i waiting on condition.", status); - } - } - mSet = false; - - status = pthread_mutex_unlock(&mMutex); - if (status) { - LOGE("LocklessCommandFifo: error %i unlocking for condition.", status); - } +void LocklessCommandFifo::dumpState(const char *s) const { + LOGV("%s %p put %p, get %p, buf %p, end %p", s, this, mPut, mGet, mBuffer, mEnd); } |