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;
31d216dafa216f3329577ab624cdc5a5d1860ec035Stephen Hines    mDH = NULL;
32b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    mName = NULL;
33225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
34225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#if RS_OBJECT_DEBUG
35d216dafa216f3329577ab624cdc5a5d1860ec035Stephen Hines    mDH = new DebugHelper();
36225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#endif
372353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
382353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    rsAssert(rsc);
392353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    add();
406598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p con", this);
41326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
42326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
43afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukObjectBase::~ObjectBase() {
44a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams    //ALOGE("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
45225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#if RS_OBJECT_DEBUG
46d216dafa216f3329577ab624cdc5a5d1860ec035Stephen Hines    mDH->dump();
47d216dafa216f3329577ab624cdc5a5d1860ec035Stephen Hines    delete mDH;
48d216dafa216f3329577ab624cdc5a5d1860ec035Stephen Hines    mDH = NULL;
49225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams#endif
50225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
51b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    free(const_cast<char *>(mName));
52b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines
53afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mPrev || mNext) {
54225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // While the normal practice is to call remove before we call
55225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // delete.  Its possible for objects without a re-use list
56225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // for avoiding duplication to be created on the stack.  In those
57225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // cases we need to remove ourself here.
58225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncLock();
59225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        remove();
60225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncUnlock();
61225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
62225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
639397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(!mUserRefCount);
649397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(!mSysRefCount);
65e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
66e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
67afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::dumpLOGV(const char *op) const {
68b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    if (mName) {
696598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("%s RSobj %p, name %s, refs %i,%i  links %p,%p,%p",
70b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines             op, this, mName, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
71f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    } else {
726598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("%s RSobj %p, no-name, refs %i,%i  links %p,%p,%p",
73225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams             op, this, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
74f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    }
75f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams}
76f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
77afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::incUserRef() const {
780b575de8ed0b628d84d256f5846500b0385979bdTim Murray    __sync_fetch_and_add(&mUserRefCount, 1);
796598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
80326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
81326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
82afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::incSysRef() const {
830b575de8ed0b628d84d256f5846500b0385979bdTim Murray    __sync_fetch_and_add(&mSysRefCount, 1);
846598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
85326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
86326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
87afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::preDestroy() const {
889397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams}
899397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
90c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsbool ObjectBase::freeChildren() {
91c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    return false;
92c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
93c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
94afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::checkDelete(const ObjectBase *ref) {
95225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if (!ref) {
96225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return false;
97225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
982353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
99225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
100225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // This lock protects us against the non-RS threads changing
101225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // the ref counts.  At this point we should be the only thread
102225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // working on them.
103225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if (ref->mUserRefCount || ref->mSysRefCount) {
104225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncUnlock();
105225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return false;
1069397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
107225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
108225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ref->remove();
109225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // At this point we can unlock because there should be no possible way
110225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // for another thread to reference this object.
111225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ref->preDestroy();
112225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
113225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    delete ref;
114225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return true;
1159397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams}
1169397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
117afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::decUserRef() const {
118e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(mUserRefCount > 0);
119f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams#if RS_OBJECT_DEBUG
120110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    //ALOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
121f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (mUserRefCount <= 0) {
122d216dafa216f3329577ab624cdc5a5d1860ec035Stephen Hines        mDH->dump();
123f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
124f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams#endif
125f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
126f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
1270b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if ((__sync_fetch_and_sub(&mUserRefCount, 1) <= 1)) {
1280b575de8ed0b628d84d256f5846500b0385979bdTim Murray        __sync_synchronize();
1290b575de8ed0b628d84d256f5846500b0385979bdTim Murray        if (mSysRefCount <= 0) {
1300b575de8ed0b628d84d256f5846500b0385979bdTim Murray            return checkDelete(this);
1310b575de8ed0b628d84d256f5846500b0385979bdTim Murray        }
132225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
133225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
134e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
135e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
136afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::zeroUserRef() const {
1376598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
1380b575de8ed0b628d84d256f5846500b0385979bdTim Murray    __sync_and_and_fetch(&mUserRefCount, 0);
13961c86951f6a1192fafc536aee613beb6f899064bStephen Hines    if (mSysRefCount <= 0) {
14061c86951f6a1192fafc536aee613beb6f899064bStephen Hines        return checkDelete(this);
141225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
142225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
143e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
144e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
145afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::decSysRef() const {
1466598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
1479397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(mSysRefCount > 0);
1480b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if ((__sync_fetch_and_sub(&mSysRefCount, 1) <= 1)) {
1490b575de8ed0b628d84d256f5846500b0385979bdTim Murray        __sync_synchronize();
1500b575de8ed0b628d84d256f5846500b0385979bdTim Murray        if (mUserRefCount <= 0) {
1510b575de8ed0b628d84d256f5846500b0385979bdTim Murray            return checkDelete(this);
1520b575de8ed0b628d84d256f5846500b0385979bdTim Murray        }
153225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
154225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
155326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
156326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
157afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::setName(const char *name) {
158b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    mName = strdup(name);
159a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams}
160a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams
161afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::setName(const char *name, uint32_t len) {
162b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    char *c = (char*)calloc(len + 1, sizeof(char));
163b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    rsAssert(c);
164b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    memcpy(c, name, len);
165b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    mName = c;
166a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams}
167a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams
168afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::asyncLock() {
1692353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    pthread_mutex_lock(&gObjectInitMutex);
1702353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams}
1712353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
172afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::asyncUnlock() {
1732353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    pthread_mutex_unlock(&gObjectInitMutex);
1742353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams}
1752353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
176afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::add() const {
177225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
1782353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
179e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(!mNext);
180e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(!mPrev);
181e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mNext = mRSC->mObjHead;
182e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mRSC->mObjHead) {
183e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mRSC->mObjHead->mPrev = this;
184e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
185e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mRSC->mObjHead = this;
1862353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
187225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
188e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
189e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
190afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::remove() const {
191e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (!mRSC) {
192e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        rsAssert(!mPrev);
193e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        rsAssert(!mNext);
194e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        return;
195e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
1962353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
197e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mRSC->mObjHead == this) {
198e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mRSC->mObjHead = mNext;
199e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
200e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mPrev) {
201e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mPrev->mNext = mNext;
202e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
203e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mNext) {
204e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mNext->mPrev = mPrev;
205e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
206e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mPrev = NULL;
207e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mNext = NULL;
208e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
209e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
210afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::zeroAllUserRef(Context *rsc) {
2111fddd90849deaae89b546ff492c345d485bbce42Jason Sams    if (rsc->props.mLogObjects) {
2126598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Forcing release of all outstanding user refs.");
2131fddd90849deaae89b546ff492c345d485bbce42Jason Sams    }
214e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
215e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    // This operation can be slow, only to be called during context cleanup.
216e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    const ObjectBase * o = rsc->mObjHead;
217e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    while (o) {
218af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("o %p", o);
219e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        if (o->zeroUserRef()) {
220e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            // deleted the object and possibly others, restart from head.
221e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            o = rsc->mObjHead;
222af12ac6a08651464f8d823add667c706f993b587Steve Block            //ALOGE("o head %p", o);
223e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        } else {
224e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            o = o->mNext;
225af12ac6a08651464f8d823add667c706f993b587Steve Block            //ALOGE("o next %p", o);
226e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        }
227e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
228f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
229f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    if (rsc->props.mLogObjects) {
2306598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Objects remaining.");
23125afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        dumpAll(rsc);
232f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    }
233e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
234e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
235c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsvoid ObjectBase::freeAllChildren(Context *rsc) {
236c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    if (rsc->props.mLogObjects) {
2376598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Forcing release of all child objects.");
238c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
239c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
240c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    // This operation can be slow, only to be called during context cleanup.
241c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    ObjectBase * o = (ObjectBase *)rsc->mObjHead;
242c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    while (o) {
243c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        if (o->freeChildren()) {
244c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            // deleted ref to self and possibly others, restart from head.
245c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            o = (ObjectBase *)rsc->mObjHead;
246c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        } else {
247c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            o = (ObjectBase *)o->mNext;
248c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        }
249c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
250c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
251c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    if (rsc->props.mLogObjects) {
2526598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Objects remaining.");
253c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        dumpAll(rsc);
254c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
255c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
256c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
257afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::dumpAll(Context *rsc) {
258225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
2592353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
2606598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("Dumping all objects");
26125afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams    const ObjectBase * o = rsc->mObjHead;
26225afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams    while (o) {
2636598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV(" Object %p", o);
26425afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        o->dumpLOGV("  ");
26525afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        o = o->mNext;
266c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
2672353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
268225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
269c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
270c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
271afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj) {
272225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
2732353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
274605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    const ObjectBase * o = rsc->mObjHead;
275605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    while (o) {
276605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        if (o == obj) {
277225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams            asyncUnlock();
278605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams            return true;
279605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        }
280605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        o = o->mNext;
281605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    }
282225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
283605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    return false;
284605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams}
285a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams
286a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Samsvoid ObjectBase::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
287a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams    //ALOGE("ObjectBase::callUpdateCacheObject %p  %p", this, dstObj);
288a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams    *((const void **)dstObj) = this;
289a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams}
290a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams
291