summaryrefslogtreecommitdiffstats
path: root/libs/rs/rsObjectBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsObjectBase.cpp')
-rw-r--r--libs/rs/rsObjectBase.cpp121
1 files changed, 89 insertions, 32 deletions
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 677413e..e4b07c4 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -15,22 +15,30 @@
*/
#include "rsObjectBase.h"
+
+#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#endif
using namespace android;
using namespace android::renderscript;
+pthread_mutex_t ObjectBase::gObjectInitMutex = PTHREAD_MUTEX_INITIALIZER;
+
ObjectBase::ObjectBase(Context *rsc)
{
mUserRefCount = 0;
mSysRefCount = 0;
- mName = NULL;
- mRSC = NULL;
+ mRSC = rsc;
mNext = NULL;
mPrev = NULL;
mAllocFile = __FILE__;
mAllocLine = __LINE__;
- setContext(rsc);
+
+ rsAssert(rsc);
+ add();
}
ObjectBase::~ObjectBase()
@@ -39,50 +47,55 @@ ObjectBase::~ObjectBase()
rsAssert(!mUserRefCount);
rsAssert(!mSysRefCount);
remove();
- delete[] mName;
}
void ObjectBase::dumpLOGV(const char *op) const
{
- if (mName) {
+ if (mName.size()) {
LOGV("%s RSobj %p, name %s, refs %i,%i from %s,%i links %p,%p,%p",
- op, this, mName, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
+ op, this, mName.string(), mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
} else {
LOGV("%s RSobj %p, no-name, refs %i,%i from %s,%i links %p,%p,%p",
op, this, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
}
}
-void ObjectBase::setContext(Context *rsc)
+void ObjectBase::incUserRef() const
{
- if (mRSC) {
- remove();
- }
- 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, mRefCount);
+ mUserRefCount++;
}
void ObjectBase::incSysRef() const
{
mSysRefCount ++;
- //LOGV("ObjectBase %p inc ref %i", this, mRefCount);
+ //LOGV("ObjectBase %p inc ref %i", this, mSysRefCount);
}
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;
@@ -90,45 +103,59 @@ bool ObjectBase::checkDelete() const
bool ObjectBase::decUserRef() const
{
+ lockUserRef();
rsAssert(mUserRefCount > 0);
- mUserRefCount --;
- //dumpObj("decUserRef");
- return checkDelete();
+ //dumpLOGV("decUserRef");
+ 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;
- //dumpObj("zeroUserRef");
- return checkDelete();
+ //dumpLOGV("zeroUserRef");
+ unlockUserRef();
+ bool ret = checkDelete();
+ return ret;
}
bool ObjectBase::decSysRef() const
{
rsAssert(mSysRefCount > 0);
mSysRefCount --;
- //dumpObj("decSysRef");
+ //dumpLOGV("decSysRef");
return checkDelete();
}
void ObjectBase::setName(const char *name)
{
- setName(name, strlen(name));
+ mName.setTo(name);
}
void ObjectBase::setName(const char *name, uint32_t len)
{
- delete mName;
- mName = NULL;
- if (name) {
- mName = new char[len + 1];
- memcpy(mName, name, len);
- mName[len] = 0;
- }
+ 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);
@@ -137,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;
}
@@ -162,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.");
}
@@ -184,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) {
@@ -195,5 +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;
}