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"
1984bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams#include "rsDebugHelper.h"
20225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
21326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
22326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
23326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
242353ae303868d04e3a26002b2f2dc456c15e8170Jason Samspthread_mutex_t ObjectBase::gObjectInitMutex = PTHREAD_MUTEX_INITIALIZER;
252353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
26afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukObjectBase::ObjectBase(Context *rsc) {
279397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    mUserRefCount = 0;
289397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    mSysRefCount = 0;
292353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    mRSC = rsc;
3044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mNext = nullptr;
3144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mPrev = nullptr;
3244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mDH = nullptr;
3344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mName = nullptr;
34225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
3584bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugStacks || gDebugReferences || gDebugLeaks) {
3684bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        mDH = new DebugHelper();
3784bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
382353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
392353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    rsAssert(rsc);
402353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    add();
4184bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams
4284bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugLifetime || gDebugReferences) {
4384bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        ALOGV("ObjectBase constructed %p", this);
4484bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
45326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
46326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
47afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukObjectBase::~ObjectBase() {
4884bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugLifetime || gDebugReferences) {
4984bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        ALOGV("ObjectBase destroyed %p   refs %i %i", this, mUserRefCount, mSysRefCount);
5084bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
5184bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams
5284bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugStacks || gDebugReferences || gDebugLeaks) {
5384bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        if (gDebugStacks || gDebugReferences) {
5484bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams            mDH->dump();
5584bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        }
5684bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        delete mDH;
5784bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        mDH = nullptr;
5884bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
59225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
60b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    free(const_cast<char *>(mName));
61b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines
62afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mPrev || mNext) {
63225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // While the normal practice is to call remove before we call
64225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // delete.  Its possible for objects without a re-use list
65225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // for avoiding duplication to be created on the stack.  In those
66225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        // cases we need to remove ourself here.
67225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncLock();
68225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        remove();
69225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncUnlock();
70225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
71225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
729397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(!mUserRefCount);
739397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(!mSysRefCount);
74e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
75e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
76afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::dumpLOGV(const char *op) const {
77b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    if (mName) {
786598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("%s RSobj %p, name %s, refs %i,%i  links %p,%p,%p",
79b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines             op, this, mName, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
80f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    } else {
816598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("%s RSobj %p, no-name, refs %i,%i  links %p,%p,%p",
82225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams             op, this, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
83f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    }
84f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams}
85f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
86afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::incUserRef() const {
870b575de8ed0b628d84d256f5846500b0385979bdTim Murray    __sync_fetch_and_add(&mUserRefCount, 1);
8884bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences) {
8984bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        ALOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
9084bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
91326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
92326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
93afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::incSysRef() const {
940b575de8ed0b628d84d256f5846500b0385979bdTim Murray    __sync_fetch_and_add(&mSysRefCount, 1);
9584bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences) {
9684bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        ALOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
9784bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
98326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
99326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
100afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::preDestroy() const {
1019397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams}
1029397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
103c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsbool ObjectBase::freeChildren() {
104c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    return false;
105c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
106c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
107afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::checkDelete(const ObjectBase *ref) {
108225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if (!ref) {
109225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return false;
110225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
1112353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
112225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
113225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // This lock protects us against the non-RS threads changing
114225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // the ref counts.  At this point we should be the only thread
115225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // working on them.
116225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    if (ref->mUserRefCount || ref->mSysRefCount) {
117225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        asyncUnlock();
118225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        return false;
1199397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
120225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams
121225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ref->remove();
122225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // At this point we can unlock because there should be no possible way
123225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    // for another thread to reference this object.
124225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ref->preDestroy();
125225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
126225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    delete ref;
127225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return true;
1289397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams}
1299397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
130afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::decUserRef() const {
131e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(mUserRefCount > 0);
13284bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences) {
13384bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        ALOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
13484bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        if (mUserRefCount <= 0) {
13584bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams            mDH->dump();
13684bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        }
137f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
138f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
139f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
1400b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if ((__sync_fetch_and_sub(&mUserRefCount, 1) <= 1)) {
1410b575de8ed0b628d84d256f5846500b0385979bdTim Murray        __sync_synchronize();
1420b575de8ed0b628d84d256f5846500b0385979bdTim Murray        if (mSysRefCount <= 0) {
1430b575de8ed0b628d84d256f5846500b0385979bdTim Murray            return checkDelete(this);
1440b575de8ed0b628d84d256f5846500b0385979bdTim Murray        }
145225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
146225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
147e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
148e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
149afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::zeroUserRef() const {
15084bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences) {
15184bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        ALOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
15284bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
15384bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams
1540b575de8ed0b628d84d256f5846500b0385979bdTim Murray    __sync_and_and_fetch(&mUserRefCount, 0);
15561c86951f6a1192fafc536aee613beb6f899064bStephen Hines    if (mSysRefCount <= 0) {
15661c86951f6a1192fafc536aee613beb6f899064bStephen Hines        return checkDelete(this);
157225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
158225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
159e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
160e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
161afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::decSysRef() const {
16284bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences) {
16384bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        ALOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
16484bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    }
16584bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams
1669397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    rsAssert(mSysRefCount > 0);
1670b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if ((__sync_fetch_and_sub(&mSysRefCount, 1) <= 1)) {
1680b575de8ed0b628d84d256f5846500b0385979bdTim Murray        __sync_synchronize();
1690b575de8ed0b628d84d256f5846500b0385979bdTim Murray        if (mUserRefCount <= 0) {
1700b575de8ed0b628d84d256f5846500b0385979bdTim Murray            return checkDelete(this);
1710b575de8ed0b628d84d256f5846500b0385979bdTim Murray        }
172225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    }
173225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    return false;
174326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
175326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
176afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::setName(const char *name) {
177b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    mName = strdup(name);
178a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams}
179a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams
180afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::setName(const char *name, uint32_t len) {
181b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    char *c = (char*)calloc(len + 1, sizeof(char));
182b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    rsAssert(c);
183b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    memcpy(c, name, len);
184b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines    mName = c;
185a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams}
186a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams
187afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::asyncLock() {
1882353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    pthread_mutex_lock(&gObjectInitMutex);
1892353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams}
1902353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
191afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::asyncUnlock() {
1922353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams    pthread_mutex_unlock(&gObjectInitMutex);
1932353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams}
1942353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
195afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::add() const {
196225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
1972353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
198e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(!mNext);
199e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    rsAssert(!mPrev);
200e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mNext = mRSC->mObjHead;
201e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mRSC->mObjHead) {
202e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mRSC->mObjHead->mPrev = this;
203e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
204e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    mRSC->mObjHead = this;
2052353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
206225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
207e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
208e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
209afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::remove() const {
210e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (!mRSC) {
211e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        rsAssert(!mPrev);
212e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        rsAssert(!mNext);
213e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        return;
214e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
2152353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
216e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mRSC->mObjHead == this) {
217e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mRSC->mObjHead = mNext;
218e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
219e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mPrev) {
220e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mPrev->mNext = mNext;
221e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
222e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    if (mNext) {
223e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        mNext->mPrev = mPrev;
224e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
22544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mPrev = nullptr;
22644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mNext = nullptr;
227e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
228e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
229afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::zeroAllUserRef(Context *rsc) {
23084bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences || gDebugLeaks) {
2316598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Forcing release of all outstanding user refs.");
2321fddd90849deaae89b546ff492c345d485bbce42Jason Sams    }
233e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
234e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    // This operation can be slow, only to be called during context cleanup.
235e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    const ObjectBase * o = rsc->mObjHead;
236e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    while (o) {
237af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("o %p", o);
238e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        if (o->zeroUserRef()) {
239e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            // deleted the object and possibly others, restart from head.
240e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            o = rsc->mObjHead;
241af12ac6a08651464f8d823add667c706f993b587Steve Block            //ALOGE("o head %p", o);
242e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        } else {
243e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams            o = o->mNext;
244af12ac6a08651464f8d823add667c706f993b587Steve Block            //ALOGE("o next %p", o);
245e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams        }
246e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    }
247f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
24884bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences || gDebugLeaks) {
2496598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Objects remaining.");
25025afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        dumpAll(rsc);
251f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    }
252e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams}
253e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams
254c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsvoid ObjectBase::freeAllChildren(Context *rsc) {
25584bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences) {
2566598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Forcing release of all child objects.");
257c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
258c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
259c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    // This operation can be slow, only to be called during context cleanup.
260c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    ObjectBase * o = (ObjectBase *)rsc->mObjHead;
261c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    while (o) {
262c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        if (o->freeChildren()) {
263c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            // deleted ref to self and possibly others, restart from head.
264c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            o = (ObjectBase *)rsc->mObjHead;
265c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        } else {
266c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams            o = (ObjectBase *)o->mNext;
267c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        }
268c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
269c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
27084bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams    if (gDebugReferences) {
2716598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV("Objects remaining.");
272c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        dumpAll(rsc);
273c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
274c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
275c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
276afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ObjectBase::dumpAll(Context *rsc) {
277225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
2782353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
2796598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("Dumping all objects");
28025afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams    const ObjectBase * o = rsc->mObjHead;
28125afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams    while (o) {
2826598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        ALOGV(" Object %p", o);
28325afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        o->dumpLOGV("  ");
28484bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        if (o->mDH != nullptr) {
28584bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams            o->mDH->dump();
28684bf95dece5bdac4a56b6f40c160e85cc7bb9732Jason Sams        }
28725afc007f33952d6ba10297f7bab4053d30e2f72Jason Sams        o = o->mNext;
288c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
2892353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
290225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
291c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
292c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
293afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj) {
294225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncLock();
2952353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams
296605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    const ObjectBase * o = rsc->mObjHead;
297605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    while (o) {
298605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        if (o == obj) {
299225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams            asyncUnlock();
300605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams            return true;
301605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        }
302605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams        o = o->mNext;
303605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    }
304225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    asyncUnlock();
305605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams    return false;
306605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams}
307a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams
308a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Samsvoid ObjectBase::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
309a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams    //ALOGE("ObjectBase::callUpdateCacheObject %p  %p", this, dstObj);
310a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams    *((const void **)dstObj) = this;
311a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams}
312a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams
313