summaryrefslogtreecommitdiffstats
path: root/libs/rs/rsLocklessFifo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsLocklessFifo.cpp')
-rw-r--r--libs/rs/rsLocklessFifo.cpp161
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);
}