Replace spins with proper pthread conditions.

This commit is contained in:
Jason Sams
2009-06-18 16:58:42 -07:00
parent f8cd5d9988
commit 5f7fc27dce
5 changed files with 112 additions and 24 deletions

View File

@@ -130,14 +130,10 @@ void * Context::threadProc(void *vrsc)
rsc->mRunning = true;
bool mDraw = true;
while (!rsc->mExit) {
mDraw |= gIO->playCoreCommands(rsc);
mDraw |= gIO->playCoreCommands(rsc, !mDraw);
mDraw &= (rsc->mRootScript.get() != NULL);
if (!mDraw || !rsc->mRootScript.get()) {
usleep(10000);
continue;
}
if (rsc->mRootScript.get()) {
if (mDraw) {
mDraw = rsc->runRootScript();
eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
}

View File

@@ -37,16 +37,8 @@ bool LocklessCommandFifo::init(uint32_t sizeInBytes)
return false;
}
int status = pthread_mutex_init(&mMutex, NULL);
if (status) {
LOGE("LocklessFifo mutex init failure");
free(mBuffer);
return false;
}
status = pthread_cond_init(&mCondition, NULL);
if (status) {
LOGE("LocklessFifo condition init failure");
pthread_mutex_destroy(&mMutex);
if (!mSignalToControl.init() || !mSignalToWorker.init()) {
LOGE("Signal setup failed");
free(mBuffer);
return false;
}
@@ -106,6 +98,7 @@ void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes)
mPut += ((sizeInBytes + 3) & ~3) + 4;
//dumpState("commit 2");
mSignalToWorker.set();
}
void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes)
@@ -118,7 +111,7 @@ void LocklessCommandFifo::flush()
{
//dumpState("flush 1");
while(mPut != mGet) {
usleep(1);
mSignalToControl.wait();
}
//dumpState("flush 2");
}
@@ -126,8 +119,10 @@ void LocklessCommandFifo::flush()
const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData)
{
while(1) {
//dumpState("get");
while(isEmpty()) {
usleep(10);
mSignalToControl.set();
mSignalToWorker.wait();
}
//dumpState("get 3");
@@ -149,6 +144,9 @@ void LocklessCommandFifo::next()
{
uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
mGet += ((bytes + 3) & ~3) + 4;
if (isEmpty()) {
mSignalToControl.set();
}
//dumpState("next");
}
@@ -179,4 +177,79 @@ void LocklessCommandFifo::dumpState(const char *s) const
LOGE("%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);
return false;
}
return true;
}
void LocklessCommandFifo::Signal::set()
{
int status;
status = pthread_mutex_lock(&mMutex);
if (status) {
LOGE("LocklessCommandFifo: error %i locking for set condition.", status);
return;
}
mSet = true;
status = pthread_cond_signal(&mCondition);
if (status) {
LOGE("LocklessCommandFifo: error %i on set condition.", status);
}
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);
}
}

View File

@@ -41,14 +41,32 @@ public:
protected:
class Signal {
public:
Signal();
~Signal();
bool init();
void set();
void wait();
protected:
bool mSet;
pthread_mutex_t mMutex;
pthread_cond_t mCondition;
};
uint8_t * volatile mPut;
uint8_t * volatile mGet;
uint8_t * mBuffer;
uint8_t * mEnd;
uint8_t mSize;
pthread_mutex_t mMutex;
pthread_cond_t mCondition;
Signal mSignalToWorker;
Signal mSignalToControl;
public:
void * reserve(uint32_t bytes);

View File

@@ -34,16 +34,17 @@ ThreadIO::~ThreadIO()
{
}
bool ThreadIO::playCoreCommands(Context *con)
bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand)
{
//LOGE("playCoreCommands 1");
uint32_t cmdID = 0;
uint32_t cmdSize = 0;
bool ret = false;
while(!mToCore.isEmpty()) {
while(!mToCore.isEmpty() || waitForCommand) {
ret = true;
//LOGE("playCoreCommands 2");
const void * data = mToCore.get(&cmdID, &cmdSize);
waitForCommand = false;
//LOGE("playCoreCommands 3 %i %i", cmdID, cmdSize);
gPlaybackFuncs[cmdID](con, data);

View File

@@ -37,7 +37,7 @@ public:
// Plays back commands from the client.
// Returns true if any commands were processed.
bool playCoreCommands(Context *con);
bool playCoreCommands(Context *con, bool waitForCommand);
LocklessCommandFifo mToCore;