summaryrefslogtreecommitdiff
path: root/libs/rs/rsObjectBase.cpp
diff options
context:
space:
mode:
authorJason Sams <rjsams@android.com>2010-10-14 17:48:46 -0700
committerJason Sams <rjsams@android.com>2010-10-14 17:48:46 -0700
commit3b9c52ab8c1ab240d2299358d01a8efbe392d111 (patch)
treead86f6f761e41591de73aeaa236fa8c99105e672 /libs/rs/rsObjectBase.cpp
parentc65217e4ec3e6c80834988ec3bc66a90778ee4b0 (diff)
Async type creation.
Change-Id: I4d98446fabbf7e8a98c97f85b573a58c8a0c58c2
Diffstat (limited to 'libs/rs/rsObjectBase.cpp')
-rw-r--r--libs/rs/rsObjectBase.cpp81
1 files changed, 64 insertions, 17 deletions
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 124d5e642b22..e4b07c4c3d97 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -25,16 +25,20 @@
using namespace android;
using namespace android::renderscript;
+pthread_mutex_t ObjectBase::gObjectInitMutex = PTHREAD_MUTEX_INITIALIZER;
+
ObjectBase::ObjectBase(Context *rsc)
{
mUserRefCount = 0;
mSysRefCount = 0;
- mRSC = NULL;
+ mRSC = rsc;
mNext = NULL;
mPrev = NULL;
mAllocFile = __FILE__;
mAllocLine = __LINE__;
- setContext(rsc);
+
+ rsAssert(rsc);
+ add();
}
ObjectBase::~ObjectBase()
@@ -56,22 +60,17 @@ void ObjectBase::dumpLOGV(const char *op) const
}
}
-void ObjectBase::setContext(Context *rsc)
+void ObjectBase::incUserRef() const
{
- if (mRSC) {
- remove();
- }
- rsAssert(rsc);
- mRSC = rsc;
- if (rsc) {
- add();
- }
+ lockUserRef();
+ mUserRefCount++;
+ unlockUserRef();
+ //LOGV("ObjectBase %p inc ref %i", this, mUserRefCount);
}
-void ObjectBase::incUserRef() const
+void ObjectBase::prelockedIncUserRef() const
{
- mUserRefCount ++;
- //LOGV("ObjectBase %p inc ref %i", this, mUserRefCount);
+ mUserRefCount++;
}
void ObjectBase::incSysRef() const
@@ -83,10 +82,20 @@ void ObjectBase::incSysRef() const
bool ObjectBase::checkDelete() const
{
if (!(mSysRefCount | mUserRefCount)) {
+ lockUserRef();
+
+ // Recheck the user ref count since it can be incremented from other threads.
+ if (mUserRefCount) {
+ unlockUserRef();
+ return false;
+ }
+
if (mRSC && mRSC->props.mLogObjects) {
dumpLOGV("checkDelete");
}
delete this;
+
+ unlockUserRef();
return true;
}
return false;
@@ -94,17 +103,25 @@ bool ObjectBase::checkDelete() const
bool ObjectBase::decUserRef() const
{
+ lockUserRef();
rsAssert(mUserRefCount > 0);
- mUserRefCount --;
//dumpLOGV("decUserRef");
- return checkDelete();
+ mUserRefCount--;
+ unlockUserRef();
+ bool ret = checkDelete();
+ return ret;
}
bool ObjectBase::zeroUserRef() const
{
+ lockUserRef();
+ // This can only happen during cleanup and is therefore
+ // thread safe.
mUserRefCount = 0;
//dumpLOGV("zeroUserRef");
- return checkDelete();
+ unlockUserRef();
+ bool ret = checkDelete();
+ return ret;
}
bool ObjectBase::decSysRef() const
@@ -125,8 +142,20 @@ void ObjectBase::setName(const char *name, uint32_t len)
mName.setTo(name, len);
}
+void ObjectBase::lockUserRef()
+{
+ pthread_mutex_lock(&gObjectInitMutex);
+}
+
+void ObjectBase::unlockUserRef()
+{
+ pthread_mutex_unlock(&gObjectInitMutex);
+}
+
void ObjectBase::add() const
{
+ pthread_mutex_lock(&gObjectInitMutex);
+
rsAssert(!mNext);
rsAssert(!mPrev);
//LOGV("calling add rsc %p", mRSC);
@@ -135,16 +164,22 @@ void ObjectBase::add() const
mRSC->mObjHead->mPrev = this;
}
mRSC->mObjHead = this;
+
+ pthread_mutex_unlock(&gObjectInitMutex);
}
void ObjectBase::remove() const
{
+ // Should be within gObjectInitMutex lock
+ // lock will be from checkDelete a few levels up in the stack.
+
//LOGV("calling remove rsc %p", mRSC);
if (!mRSC) {
rsAssert(!mPrev);
rsAssert(!mNext);
return;
}
+
if (mRSC->mObjHead == this) {
mRSC->mObjHead = mNext;
}
@@ -160,6 +195,8 @@ void ObjectBase::remove() const
void ObjectBase::zeroAllUserRef(Context *rsc)
{
+ lockUserRef();
+
if (rsc->props.mLogObjects) {
LOGV("Forcing release of all outstanding user refs.");
}
@@ -182,10 +219,14 @@ void ObjectBase::zeroAllUserRef(Context *rsc)
LOGV("Objects remaining.");
dumpAll(rsc);
}
+
+ unlockUserRef();
}
void ObjectBase::dumpAll(Context *rsc)
{
+ lockUserRef();
+
LOGV("Dumping all objects");
const ObjectBase * o = rsc->mObjHead;
while (o) {
@@ -193,17 +234,23 @@ void ObjectBase::dumpAll(Context *rsc)
o->dumpLOGV(" ");
o = o->mNext;
}
+
+ unlockUserRef();
}
bool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj)
{
+ lockUserRef();
+
const ObjectBase * o = rsc->mObjHead;
while (o) {
if (o == obj) {
+ unlockUserRef();
return true;
}
o = o->mNext;
}
+ unlockUserRef();
return false;
}