10f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines/*
20f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Copyright (C) 2009 The Android Open Source Project
30f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *
40f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
50f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * you may not use this file except in compliance with the License.
60f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * You may obtain a copy of the License at
70f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *
80f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *      http://www.apache.org/licenses/LICENSE-2.0
90f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *
100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Unless required by applicable law or agreed to in writing, software
110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * See the License for the specific language governing permissions and
140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * limitations under the License.
150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines */
160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsObjectBase.h"
180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsContext.h"
190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesusing namespace android;
210f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesusing namespace android::renderscript;
220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinespthread_mutex_t ObjectBase::gObjectInitMutex = PTHREAD_MUTEX_INITIALIZER;
240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen HinesObjectBase::ObjectBase(Context *rsc) {
260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mUserRefCount = 0;
270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mSysRefCount = 0;
280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mRSC = rsc;
290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mNext = NULL;
300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mPrev = NULL;
310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#if RS_OBJECT_DEBUG
330f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mStack.update(2);
340f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#endif
350f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(rsc);
370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    add();
380f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("ObjectBase %p con", this);
390f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
400f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
410f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen HinesObjectBase::~ObjectBase() {
420f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
430f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#if RS_OBJECT_DEBUG
440f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mStack.dump();
450f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#endif
460f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (mPrev || mNext) {
480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        // While the normal practice is to call remove before we call
490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        // delete.  Its possible for objects without a re-use list
500f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        // for avoiding duplication to be created on the stack.  In those
510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        // cases we need to remove ourself here.
520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        asyncLock();
530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        remove();
540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        asyncUnlock();
550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(!mUserRefCount);
580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(!mSysRefCount);
590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::dumpLOGV(const char *op) const {
620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (mName.size()) {
630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGV("%s RSobj %p, name %s, refs %i,%i  links %p,%p,%p",
640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines             op, this, mName.string(), mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    } else {
660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGV("%s RSobj %p, no-name, refs %i,%i  links %p,%p,%p",
670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines             op, this, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
690f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
700f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
710f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::incUserRef() const {
720f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    android_atomic_inc(&mUserRefCount);
730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
750f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
760f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::incSysRef() const {
770f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    android_atomic_inc(&mSysRefCount);
780f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
790f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
800f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
810f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::preDestroy() const {
820f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
830f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
840f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ObjectBase::freeChildren() {
850f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return false;
860f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
870f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
880f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ObjectBase::checkDelete(const ObjectBase *ref) {
890f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (!ref) {
900f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return false;
910f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
920f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
930f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncLock();
940f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // This lock protects us against the non-RS threads changing
950f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // the ref counts.  At this point we should be the only thread
960f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // working on them.
970f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (ref->mUserRefCount || ref->mSysRefCount) {
980f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        asyncUnlock();
990f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return false;
1000f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1010f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1020f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    ref->remove();
1030f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // At this point we can unlock because there should be no possible way
1040f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // for another thread to reference this object.
1050f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    ref->preDestroy();
1060f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncUnlock();
1070f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    delete ref;
1080f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return true;
1090f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ObjectBase::decUserRef() const {
1120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(mUserRefCount > 0);
1130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#if RS_OBJECT_DEBUG
1140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    ALOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
1150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (mUserRefCount <= 0) {
1160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        mStack.dump();
1170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#endif
1190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1210f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if ((android_atomic_dec(&mUserRefCount) <= 1) &&
1220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        (android_atomic_acquire_load(&mSysRefCount) <= 0)) {
1230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return checkDelete(this);
1240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return false;
1260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ObjectBase::zeroUserRef() const {
1290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
1300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    android_atomic_acquire_store(0, &mUserRefCount);
1310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (android_atomic_acquire_load(&mSysRefCount) <= 0) {
1320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return checkDelete(this);
1330f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1340f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return false;
1350f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ObjectBase::decSysRef() const {
1380f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
1390f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(mSysRefCount > 0);
1400f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if ((android_atomic_dec(&mSysRefCount) <= 1) &&
1410f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        (android_atomic_acquire_load(&mUserRefCount) <= 0)) {
1420f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return checkDelete(this);
1430f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1440f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return false;
1450f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1460f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::setName(const char *name) {
1480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mName.setTo(name);
1490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1500f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::setName(const char *name, uint32_t len) {
1520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mName.setTo(name, len);
1530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::asyncLock() {
1560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_mutex_lock(&gObjectInitMutex);
1570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::asyncUnlock() {
1600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_mutex_unlock(&gObjectInitMutex);
1610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::add() const {
1640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncLock();
1650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(!mNext);
1670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(!mPrev);
1680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("calling add  rsc %p", mRSC);
1690f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mNext = mRSC->mObjHead;
1700f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (mRSC->mObjHead) {
1710f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        mRSC->mObjHead->mPrev = this;
1720f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mRSC->mObjHead = this;
1740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1750f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncUnlock();
1760f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1770f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1780f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::remove() const {
1790f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("calling remove  rsc %p", mRSC);
1800f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (!mRSC) {
1810f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsAssert(!mPrev);
1820f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsAssert(!mNext);
1830f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return;
1840f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1850f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1860f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (mRSC->mObjHead == this) {
1870f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        mRSC->mObjHead = mNext;
1880f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1890f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (mPrev) {
1900f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        mPrev->mNext = mNext;
1910f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1920f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (mNext) {
1930f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        mNext->mPrev = mPrev;
1940f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1950f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mPrev = NULL;
1960f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    mNext = NULL;
1970f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1980f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1990f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::zeroAllUserRef(Context *rsc) {
2000f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (rsc->props.mLogObjects) {
2010f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGV("Forcing release of all outstanding user refs.");
2020f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2030f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2040f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // This operation can be slow, only to be called during context cleanup.
2050f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    const ObjectBase * o = rsc->mObjHead;
2060f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    while (o) {
2070f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        //ALOGE("o %p", o);
2080f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        if (o->zeroUserRef()) {
2090f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            // deleted the object and possibly others, restart from head.
2100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            o = rsc->mObjHead;
2110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            //ALOGE("o head %p", o);
2120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        } else {
2130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            o = o->mNext;
2140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            //ALOGE("o next %p", o);
2150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        }
2160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (rsc->props.mLogObjects) {
2190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGV("Objects remaining.");
2200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        dumpAll(rsc);
2210f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
2230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::freeAllChildren(Context *rsc) {
2250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (rsc->props.mLogObjects) {
2260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGV("Forcing release of all child objects.");
2270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // This operation can be slow, only to be called during context cleanup.
2300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    ObjectBase * o = (ObjectBase *)rsc->mObjHead;
2310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    while (o) {
2320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        if (o->freeChildren()) {
2330f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            // deleted ref to self and possibly others, restart from head.
2340f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            o = (ObjectBase *)rsc->mObjHead;
2350f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        } else {
2360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            o = (ObjectBase *)o->mNext;
2370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        }
2380f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2390f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2400f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (rsc->props.mLogObjects) {
2410f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGV("Objects remaining.");
2420f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        dumpAll(rsc);
2430f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2440f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
2450f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2460f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ObjectBase::dumpAll(Context *rsc) {
2470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncLock();
2480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    ALOGV("Dumping all objects");
2500f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    const ObjectBase * o = rsc->mObjHead;
2510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    while (o) {
2520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGV(" Object %p", o);
2530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        o->dumpLOGV("  ");
2540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        o = o->mNext;
2550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncUnlock();
2580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
2590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj) {
2610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncLock();
2620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    const ObjectBase * o = rsc->mObjHead;
2640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    while (o) {
2650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        if (o == obj) {
2660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            asyncUnlock();
2670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            return true;
2680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        }
2690f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        o = o->mNext;
2700f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2710f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    asyncUnlock();
2720f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return false;
2730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
2740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
275