diff options
author | Jason Sams <rjsams@android.com> | 2010-10-14 17:48:46 -0700 |
---|---|---|
committer | Jason Sams <rjsams@android.com> | 2010-10-14 17:48:46 -0700 |
commit | 3b9c52ab8c1ab240d2299358d01a8efbe392d111 (patch) | |
tree | ad86f6f761e41591de73aeaa236fa8c99105e672 /libs/rs/rsObjectBase.cpp | |
parent | c65217e4ec3e6c80834988ec3bc66a90778ee4b0 (diff) |
Async type creation.
Change-Id: I4d98446fabbf7e8a98c97f85b573a58c8a0c58c2
Diffstat (limited to 'libs/rs/rsObjectBase.cpp')
-rw-r--r-- | libs/rs/rsObjectBase.cpp | 81 |
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; } |