Seperate out Mutex and Signal code into reusable classes.

Change-Id: I381d09d89b567d433a10a91e0d7e59c24d3444d8
This commit is contained in:
Jason Sams
2010-03-18 11:39:44 -07:00
parent 3cfae1bbf4
commit c1d726c2d6
10 changed files with 294 additions and 125 deletions

View File

@@ -81,12 +81,13 @@ LOCAL_SRC_FILES:= \
rsContext.cpp \
rsDevice.cpp \
rsElement.cpp \
rsFileA3D.cpp \
rsFileA3D.cpp \
rsLight.cpp \
rsLocklessFifo.cpp \
rsObjectBase.cpp \
rsMatrix.cpp \
rsMesh.cpp \
rsMesh.cpp \
rsMutex.cpp \
rsNoise.cpp \
rsProgram.cpp \
rsProgramFragment.cpp \
@@ -97,7 +98,8 @@ LOCAL_SRC_FILES:= \
rsScript.cpp \
rsScriptC.cpp \
rsScriptC_Lib.cpp \
rsShaderCache.cpp \
rsShaderCache.cpp \
rsSignal.cpp \
rsSimpleMesh.cpp \
rsThreadIO.cpp \
rsType.cpp \

View File

@@ -664,8 +664,7 @@ void Context::appendNameDefines(String8 *str) const
bool Context::objDestroyOOBInit()
{
int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL);
if (status) {
if (!mObjDestroy.mMutex.init()) {
LOGE("Context::ObjDestroyOOBInit mutex init failure");
return false;
}
@@ -675,9 +674,8 @@ bool Context::objDestroyOOBInit()
void Context::objDestroyOOBRun()
{
if (mObjDestroy.mNeedToEmpty) {
int status = pthread_mutex_lock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
if (!mObjDestroy.mMutex.lock()) {
LOGE("Context::ObjDestroyOOBRun: error locking for OOBRun.");
return;
}
@@ -686,35 +684,25 @@ void Context::objDestroyOOBRun()
}
mObjDestroy.mDestroyList.clear();
mObjDestroy.mNeedToEmpty = false;
status = pthread_mutex_unlock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
}
mObjDestroy.mMutex.unlock();
}
}
void Context::objDestroyOOBDestroy()
{
rsAssert(!mObjDestroy.mNeedToEmpty);
pthread_mutex_destroy(&mObjDestroy.mMutex);
}
void Context::objDestroyAdd(ObjectBase *obj)
{
int status = pthread_mutex_lock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
if (!mObjDestroy.mMutex.lock()) {
LOGE("Context::ObjDestroyOOBRun: error locking for OOBRun.");
return;
}
mObjDestroy.mNeedToEmpty = true;
mObjDestroy.mDestroyList.add(obj);
status = pthread_mutex_unlock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
}
mObjDestroy.mMutex.unlock();
}
uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait)

View File

@@ -18,6 +18,7 @@
#define ANDROID_RS_CONTEXT_H
#include "rsUtils.h"
#include "rsMutex.h"
#include "rsThreadIO.h"
#include "rsType.h"
@@ -227,7 +228,7 @@ protected:
struct ObjDestroyOOB {
pthread_mutex_t mMutex;
Mutex mMutex;
Vector<ObjectBase *> mDestroyList;
bool mNeedToEmpty;
};

View File

@@ -17,7 +17,7 @@
#include "rsLocklessFifo.h"
using namespace android;
using namespace android::renderscript;
LocklessCommandFifo::LocklessCommandFifo()
{
@@ -128,15 +128,19 @@ void LocklessCommandFifo::flush()
//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");
while(isEmpty() && !mInShutdown) {
mSignalToControl.set();
mSignalToWorker.wait();
}
wait();
if (mInShutdown) {
*command = 0;
*bytesData = 0;
@@ -192,79 +196,3 @@ 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);
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

@@ -19,8 +19,10 @@
#include "rsUtils.h"
#include "rsSignal.h"
namespace android {
namespace renderscript {
// A simple FIFO to be used as a producer / consumer between two
@@ -37,24 +39,7 @@ public:
LocklessCommandFifo();
~LocklessCommandFifo();
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;
@@ -65,14 +50,14 @@ protected:
Signal mSignalToWorker;
Signal mSignalToControl;
public:
void * reserve(uint32_t bytes);
void commit(uint32_t command, uint32_t bytes);
void commitSync(uint32_t command, uint32_t bytes);
void flush();
void wait();
const void * get(uint32_t *command, uint32_t *bytesData);
void next();
@@ -87,5 +72,6 @@ private:
};
}
}
#endif

64
libs/rs/rsMutex.cpp Normal file
View File

@@ -0,0 +1,64 @@
/*
* 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 "rsMutex.h"
using namespace android;
using namespace android::renderscript;
Mutex::Mutex()
{
}
Mutex::~Mutex()
{
pthread_mutex_destroy(&mMutex);
}
bool Mutex::init()
{
int status = pthread_mutex_init(&mMutex, NULL);
if (status) {
LOGE("Mutex::Mutex init failure");
return false;
}
return true;
}
bool Mutex::lock()
{
int status;
status = pthread_mutex_lock(&mMutex);
if (status) {
LOGE("Mutex: error %i locking.", status);
return false;
}
return true;
}
bool Mutex::unlock()
{
int status;
status = pthread_mutex_unlock(&mMutex);
if (status) {
LOGE("Mutex error %i unlocking.", status);
return false;
}
return true;
}

43
libs/rs/rsMutex.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* 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.
*/
#ifndef ANDROID_RS_MUTEX_H
#define ANDROID_RS_MUTEX_H
#include "rsUtils.h"
namespace android {
namespace renderscript {
class Mutex {
public:
Mutex();
~Mutex();
bool init();
bool lock();
bool unlock();
protected:
pthread_mutex_t mMutex;
};
}
}
#endif

98
libs/rs/rsSignal.cpp Normal file
View File

@@ -0,0 +1,98 @@
/*
* 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 "rsSignal.h"
using namespace android;
using namespace android::renderscript;
Signal::Signal()
{
mSet = true;
}
Signal::~Signal()
{
pthread_mutex_destroy(&mMutex);
pthread_cond_destroy(&mCondition);
}
bool 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 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 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);
}
}

46
libs/rs/rsSignal.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* 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.
*/
#ifndef ANDROID_RS_SIGNAL_H
#define ANDROID_RS_SIGNAL_H
#include "rsUtils.h"
namespace android {
namespace renderscript {
class Signal {
public:
Signal();
~Signal();
bool init();
void set();
void wait();
protected:
bool mSet;
pthread_mutex_t mMutex;
pthread_cond_t mCondition;
};
}
}
#endif

View File

@@ -7,8 +7,12 @@
struct Element;
struct ElementField {
// An Element Field is a combination of an Element with a name assigned.
const char *name;
Element *e;
ElementField(const char *n, Element *_e) {
name = n;
e = _e;
@@ -20,12 +24,21 @@ struct ElementField {
};
struct Element {
// An Element can take one of two forms.
// 1: Basic. It contains a single basic type and vector size.
// 2: Complex. It contains a list of fields with names. Each field
// will in turn be another element.
ElementField *fields;
size_t fieldCount;
size_t fieldCount; // If field count is 0, the element is a Basic type.
const char *name;
bool generated;
// The basic data type from RenderScript.h
RsDataType compType;
// The vector size of the data type for float2, float3, ....
// Allowed sizes are 2,3,4,8,16
uint32_t compVectorSize;
Element() {