1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsObjectBase.h"
18e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams#include "rsContext.h"
19225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
20326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
21326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
22326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
232353ae303868d04e3a26002b2f2dc456c15e8170Jason Samspthread_mutex_t ObjectBase::gObjectInitMutex = PTHREAD_MUTEX_INITIALIZER;
242353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
25afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukObjectBase::ObjectBase(Context *rsc) {
269397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    mUserRefCount = 0;
279397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    mSysRefCount = 0;
282353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    mRSC = rsc;
29e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mNext = NULL;
30e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mPrev = NULL;
31225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
32225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#if RS_OBJECT_DEBUG
33225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    mStack.update(2);
34225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#endif
352353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
362353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    rsAssert(rsc);
372353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    add();
386598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p con", this);
39326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
40326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
41afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukObjectBase::~ObjectBase() {
426598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
43225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#if RS_OBJECT_DEBUG
44225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    mStack.dump();
45225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#endif
46225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
47afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mPrev || mNext) {
48225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // While the normal practice is to call remove before we call
49225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // delete.  Its possible for objects without a re-use list
50225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // for avoiding duplication to be created on the stack.  In those
51225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // cases we need to remove ourself here.
52225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncLock();
53225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        remove();
54225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncUnlock();
55225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
56225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
579397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(!mUserRefCount);
589397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(!mSysRefCount);
59e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
60e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
61afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::dumpLOGV(const char *op) const {
62fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    if (mName.size()) {
636598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("%s RSobj %p, name %s, refs %i,%i  links %p,%p,%p",
64225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams             op, this, mName.string(), mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
65f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    } else {
666598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("%s RSobj %p, no-name, refs %i,%i  links %p,%p,%p",
67225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams             op, this, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
68f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    }
69f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams}
70f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
71afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::incUserRef() const {
72225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    android_atomic_inc(&mUserRefCount);
736598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
74326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
75326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
76afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::incSysRef() const {
77225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    android_atomic_inc(&mSysRefCount);
786598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
79326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
80326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
81afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::preDestroy() const {
829397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams}
839397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
84c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsbool ObjectBase::freeChildren() {
85c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    return false;
86c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
87c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
88afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::checkDelete(const ObjectBase *ref) {
89225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if (!ref) {
90225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return false;
91225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
922353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
93225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
94225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // This lock protects us against the non-RS threads changing
95225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // the ref counts.  At this point we should be the only thread
96225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // working on them.
97225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if (ref->mUserRefCount || ref->mSysRefCount) {
98225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncUnlock();
99225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return false;
1009397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
101225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
102225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ref->remove();
103225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // At this point we can unlock because there should be no possible way
104225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // for another thread to reference this object.
105225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ref->preDestroy();
106225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
107225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    delete ref;
108225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return true;
1099397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams}
1109397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
111afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::decUserRef() const {
112e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(mUserRefCount > 0);
113f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams#if RS_OBJECT_DEBUG
1146598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
115f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (mUserRefCount <= 0) {
116f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        mStack.dump();
117f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
118f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams#endif
119f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
120f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
121225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if ((android_atomic_dec(&mUserRefCount) <= 1) &&
122225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        (android_atomic_acquire_load(&mSysRefCount) <= 0)) {
123225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return checkDelete(this);
124225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
125225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
126e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
127e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
128afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::zeroUserRef() const {
1296598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
130225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    android_atomic_acquire_store(0, &mUserRefCount);
131225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if (android_atomic_acquire_load(&mSysRefCount) <= 0) {
132225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return checkDelete(this);
133225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
134225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
135e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
136e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
137afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::decSysRef() const {
1386598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
1399397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(mSysRefCount > 0);
140225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if ((android_atomic_dec(&mSysRefCount) <= 1) &&
141225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        (android_atomic_acquire_load(&mUserRefCount) <= 0)) {
142225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return checkDelete(this);
143225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
144225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
145326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
146326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
147afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::setName(const char *name) {
148fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mName.setTo(name);
149a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams}
150a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams
151afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::setName(const char *name, uint32_t len) {
152fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mName.setTo(name, len);
153a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams}
154a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams
155afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::asyncLock() {
1562353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    pthread_mutex_lock(&gObjectInitMutex);
1572353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams}
1582353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
159afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::asyncUnlock() {
1602353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    pthread_mutex_unlock(&gObjectInitMutex);
1612353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams}
1622353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
163afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::add() const {
164225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
1652353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
166e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(!mNext);
167e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(!mPrev);
1686598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("calling add  rsc %p", mRSC);
169e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mNext = mRSC->mObjHead;
170e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mRSC->mObjHead) {
171e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mRSC->mObjHead->mPrev = this;
172e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
173e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mRSC->mObjHead = this;
1742353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
175225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
176e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
177e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
178afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::remove() const {
1796598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("calling remove  rsc %p", mRSC);
180e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (!mRSC) {
181e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        rsAssert(!mPrev);
182e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        rsAssert(!mNext);
183e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        return;
184e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
1852353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
186e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mRSC->mObjHead == this) {
187e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mRSC->mObjHead = mNext;
188e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
189e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mPrev) {
190e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mPrev->mNext = mNext;
191e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
192e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mNext) {
193e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mNext->mPrev = mPrev;
194e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
195e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mPrev = NULL;
196e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mNext = NULL;
197e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
198e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
199afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::zeroAllUserRef(Context *rsc) {
2001fddd90849deaae89b546ff492c345d485bbce42Jason Sams    if (rsc->props.mLogObjects) {
2016598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Forcing release of all outstanding user refs.");
2021fddd90849deaae89b546ff492c345d485bbce42Jason Sams    }
203e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
204e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    // This operation can be slow, only to be called during context cleanup.
205e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    const ObjectBase * o = rsc->mObjHead;
206e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    while (o) {
207af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("o %p", o);
208e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        if (o->zeroUserRef()) {
209e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            // deleted the object and possibly others, restart from head.
210e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            o = rsc->mObjHead;
211af12ac6a08651464f8d823add667c706f993b587Steve Block            //ALOGE("o head %p", o);
212e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        } else {
213e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            o = o->mNext;
214af12ac6a08651464f8d823add667c706f993b587Steve Block            //ALOGE("o next %p", o);
215e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        }
216e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
217f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
218f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    if (rsc->props.mLogObjects) {
2196598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Objects remaining.");
22025afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        dumpAll(rsc);
221f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    }
222e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
223e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
224c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsvoid ObjectBase::freeAllChildren(Context *rsc) {
225c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    if (rsc->props.mLogObjects) {
2266598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Forcing release of all child objects.");
227c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
228c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
229c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    // This operation can be slow, only to be called during context cleanup.
230c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    ObjectBase * o = (ObjectBase *)rsc->mObjHead;
231c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    while (o) {
232c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        if (o->freeChildren()) {
233c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            // deleted ref to self and possibly others, restart from head.
234c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            o = (ObjectBase *)rsc->mObjHead;
235c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        } else {
236c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            o = (ObjectBase *)o->mNext;
237c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        }
238c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
239c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
240c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    if (rsc->props.mLogObjects) {
2416598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Objects remaining.");
242c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        dumpAll(rsc);
243c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
244c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
245c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
246afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::dumpAll(Context *rsc) {
247225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
2482353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
2496598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("Dumping all objects");
25025afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams    const ObjectBase * o = rsc->mObjHead;
25125afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams    while (o) {
2526598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV(" Object %p", o);
25325afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        o->dumpLOGV("  ");
25425afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        o = o->mNext;
255c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
2562353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
257225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
258c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
259c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
260afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj) {
261225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
2622353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
263605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    const ObjectBase * o = rsc->mObjHead;
264605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    while (o) {
265605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        if (o == obj) {
266225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams            asyncUnlock();
267605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams            return true;
268605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        }
269605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        o = o->mNext;
270605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    }
271225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
272605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    return false;
273605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams}
274605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams
275