diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index b9db296d3aeb6ee036cf9d90e5191bcbfe10164e..a91a00d15fe657606ec7c3c59113807e8889af23 100644 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -29,6 +29,11 @@ WeakRefCounter::WeakRefCounter(RefCounter *counter, void *cookie) } } +int WeakRefCounter::GetWeakRefCount() const +{ + return atomicWeak_.load(std::memory_order_relaxed); +} + WeakRefCounter::~WeakRefCounter() { if (refCounter_ != nullptr) { @@ -36,9 +41,11 @@ WeakRefCounter::~WeakRefCounter() } } -int WeakRefCounter::GetWeakRefCount() const +void WeakRefCounter::IncWeakRefCount(const void *objectId) { - return atomicWeak_.load(std::memory_order_relaxed); + if (atomicWeak_.fetch_add(1, std::memory_order_relaxed) == 0) { + refCounter_->IncWeakRefCount(objectId); + } } void* WeakRefCounter::GetRefPtr() @@ -49,11 +56,10 @@ void* WeakRefCounter::GetRefPtr() return cookie_; } -void WeakRefCounter::IncWeakRefCount(const void *objectId) +bool WeakRefCounter::AttemptIncStrongRef(const void *objectId) { - if (atomicWeak_.fetch_add(1, std::memory_order_relaxed) == 0) { - refCounter_->IncWeakRefCount(objectId); - } + int unuse = 0; + return refCounter_->AttemptIncStrongRef(objectId, unuse); } void WeakRefCounter::DecWeakRefCount(const void *objectId) @@ -64,12 +70,6 @@ void WeakRefCounter::DecWeakRefCount(const void *objectId) } } -bool WeakRefCounter::AttemptIncStrongRef(const void *objectId) -{ - int unuse = 0; - return refCounter_->AttemptIncStrongRef(objectId, unuse); -} - #if ((defined DEBUG_REFBASE) && (!defined PRINT_TRACK_AT_ONCE)) // RefTracker is a debug tool, used to record the trace of RefBase. // RefTracker will save the information about the count of RefBase, @@ -81,22 +81,22 @@ class RefTracker { public: RefTracker(RefTracker* exTracker, const void* id, int strong, int weak, int ref, int pid, int tid); - void PrintTrace(const void* refCounterPtr); - RefTracker* PopTrace(const void* refCounterPtr); + void PrintTrace(const void* refCounterPtr); + private: const void* ptrID; int strongRefCnt; int weakRefCnt; int refCnt; - int PID; int TID; + int PID; RefTracker* exTrace; }; RefTracker::RefTracker(RefTracker* exTracker, const void* id, int strong, int weak, int ref, int pid, int tid) - : ptrID (id), strongRefCnt (strong), weakRefCnt (weak), refCnt (ref), PID (pid), TID (tid), exTrace (exTracker) + : ptrID (id), strongRefCnt (strong), weakRefCnt (weak), refCnt (ref), TID (tid), PID (pid), exTrace (exTracker) { } @@ -109,8 +109,8 @@ void RefTracker::PrintTrace(const void* refCounterPtr) RefTracker* RefTracker::PopTrace(const void* refCounterPtr) { - RefTracker* ref = exTrace; PrintTrace(refCounterPtr); + RefTracker* ref = exTrace; delete this; return ref; } @@ -126,14 +126,6 @@ void RefCounter::PrintRefs(const void* objectId) atomicWeak_.load(std::memory_order_relaxed), atomicRefCount_.load(std::memory_order_relaxed)); } #else -void RefCounter::GetNewTrace(const void* objectId) -{ - std::lock_guard lock(trackerMutex); - RefTracker* newTracker = new RefTracker(refTracker, objectId, atomicStrong_, - atomicWeak_, atomicRefCount_, getpid(), gettid()); - refTracker = newTracker; -} - void RefCounter::PrintTracker() { std::lock_guard lock(trackerMutex); @@ -145,6 +137,14 @@ void RefCounter::PrintTracker() UTILS_LOGI("%{public}p end backtrace", this); } } + +void RefCounter::GetNewTrace(const void* objectId) +{ + std::lock_guard lock(trackerMutex); + RefTracker* newTracker = new RefTracker(refTracker, objectId, atomicStrong_, + atomicWeak_, atomicRefCount_, getpid(), gettid()); + refTracker = newTracker; +} #endif #ifndef TRACK_ALL @@ -159,6 +159,11 @@ void RefCounter::EnableTracker() #endif #endif +RefCounter::RefCounter() + : atomicStrong_(INITIAL_PRIMARY_VALUE), atomicWeak_(0), atomicRefCount_(0), atomicFlags_(0), atomicAttempt_(0) +{ +} + void RefCounter::DebugRefBase([[maybe_unused]]const void* objectId) { #ifdef DEBUG_REFBASE @@ -172,21 +177,11 @@ void RefCounter::DebugRefBase([[maybe_unused]]const void* objectId) #endif } -RefCounter::RefCounter() - : atomicStrong_(INITIAL_PRIMARY_VALUE), atomicWeak_(0), atomicRefCount_(0), atomicFlags_(0), atomicAttempt_(0) -{ -} - int RefCounter::GetRefCount() { return atomicRefCount_.load(std::memory_order_relaxed); } -void RefCounter::IncRefCount() -{ - atomicRefCount_.fetch_add(1, std::memory_order_relaxed); -} - void RefCounter::DecRefCount() { if (atomicRefCount_.load(std::memory_order_relaxed) > 0) { @@ -196,14 +191,14 @@ void RefCounter::DecRefCount() } } -void RefCounter::SetCallback(const RefPtrCallback& callback) +void RefCounter::IncRefCount() { - callback_ = callback; + atomicRefCount_.fetch_add(1, std::memory_order_relaxed); } -void RefCounter::RemoveCallback() +void RefCounter::SetCallback(const RefPtrCallback& callback) { - callback_ = nullptr; + callback_ = callback; } bool RefCounter::IsRefPtrValid() @@ -211,6 +206,11 @@ bool RefCounter::IsRefPtrValid() return callback_ != nullptr; } +void RefCounter::RemoveCallback() +{ + callback_ = nullptr; +} + RefCounter::~RefCounter() { #ifdef DEBUG_REFBASE @@ -224,20 +224,6 @@ RefCounter::~RefCounter() #endif } -int RefCounter::IncStrongRefCount(const void* objectId) -{ - DebugRefBase(objectId); - int curCount = atomicStrong_.load(std::memory_order_relaxed); - if (curCount >= 0) { - curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); - if (curCount == INITIAL_PRIMARY_VALUE) { - atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release); - } - } - - return curCount; -} - int RefCounter::DecStrongRefCount(const void* objectId) { DebugRefBase(objectId); @@ -250,7 +236,19 @@ int RefCounter::DecStrongRefCount(const void* objectId) // it may be changed after last operation. curCount = atomicStrong_.fetch_sub(1, std::memory_order_release); } + return curCount; +} +int RefCounter::IncStrongRefCount(const void* objectId) +{ + DebugRefBase(objectId); + int curCount = atomicStrong_.load(std::memory_order_relaxed); + if (curCount >= 0) { + curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); + if (curCount == INITIAL_PRIMARY_VALUE) { + atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release); + } + } return curCount; } @@ -297,19 +295,14 @@ int RefCounter::DecWeakRefCount(const void* objectId) return curCount; } -int RefCounter::GetWeakRefCount() -{ - return atomicWeak_.load(std::memory_order_relaxed); -} - void RefCounter::SetAttemptAcquire() { (void)atomicAttempt_.fetch_add(1, std::memory_order_relaxed); } -bool RefCounter::IsAttemptAcquireSet() +int RefCounter::GetWeakRefCount() { - return static_cast(atomicAttempt_.load(std::memory_order_relaxed) > 0); + return atomicWeak_.load(std::memory_order_relaxed); } void RefCounter::ClearAttemptAcquire() @@ -317,9 +310,9 @@ void RefCounter::ClearAttemptAcquire() atomicAttempt_.fetch_sub(1, std::memory_order_relaxed); } -void RefCounter::ExtendObjectLifetime() +bool RefCounter::IsAttemptAcquireSet() { - atomicFlags_.fetch_or(FLAG_EXTEND_LIFE_TIME, std::memory_order_relaxed); + return static_cast(atomicAttempt_.load(std::memory_order_relaxed) > 0); } bool RefCounter::IsLifeTimeExtended() @@ -327,42 +320,47 @@ bool RefCounter::IsLifeTimeExtended() return static_cast(atomicFlags_.load(std::memory_order_relaxed) & FLAG_EXTEND_LIFE_TIME); } +void RefCounter::ExtendObjectLifetime() +{ + atomicFlags_.fetch_or(FLAG_EXTEND_LIFE_TIME, std::memory_order_relaxed); +} + bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) { - int curCount = GetStrongRefCount(); + int refCount = GetStrongRefCount(); IncWeakRefCount(objectId); // if the object already had strong references.just promoting it. - while ((curCount > 0) && (curCount != INITIAL_PRIMARY_VALUE)) { - if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) { + while ((refCount > 0) && (refCount != INITIAL_PRIMARY_VALUE)) { + if (atomicStrong_.compare_exchange_weak(refCount, refCount + 1, std::memory_order_relaxed)) { goto ATTEMPT_SUCCESS; } // someone else changed the counter.re-acquire the counter value. - curCount = atomicStrong_.load(std::memory_order_relaxed); + refCount = atomicStrong_.load(std::memory_order_relaxed); } - if ((curCount == INITIAL_PRIMARY_VALUE) && !IsLifeTimeExtended()) { + if ((refCount == INITIAL_PRIMARY_VALUE) && !IsLifeTimeExtended()) { // this object has a "normal" life-time, - while (curCount > 0) { - if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) { + while (refCount > 0) { + if (atomicStrong_.compare_exchange_weak(refCount, refCount + 1, std::memory_order_relaxed)) { goto ATTEMPT_SUCCESS; } - curCount = atomicStrong_.load(std::memory_order_relaxed); + refCount = atomicStrong_.load(std::memory_order_relaxed); } } if (IsLifeTimeExtended()) { - curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); + refCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); } ATTEMPT_SUCCESS: - if (curCount == INITIAL_PRIMARY_VALUE) { - outCount = curCount; + if (refCount == INITIAL_PRIMARY_VALUE) { + outCount = refCount; atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release); return true; } - if (curCount < 0 || (!IsLifeTimeExtended() && curCount == 0)) { + if (refCount < 0 || (!IsLifeTimeExtended() && refCount == 0)) { // the object destroyed on strong reference count reduce to zero. DecWeakRefCount(objectId); return false; @@ -374,23 +372,17 @@ ATTEMPT_SUCCESS: bool RefCounter::AttemptIncStrong(const void *objectId) { IncWeakRefCount(objectId); - int curCount = GetStrongRefCount(); - while (curCount > 0) { - if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) { + int refCount = GetStrongRefCount(); + while (refCount > 0) { + if (atomicStrong_.compare_exchange_weak(refCount, refCount + 1, std::memory_order_relaxed)) { break; } - // curCount has been updated. + // refCount has been updated. } - if (curCount <= 0) { + if (refCount <= 0) { DecWeakRefCount(objectId); } - return curCount > 0; -} - -RefBase::RefBase() : refs_(new RefCounter()) -{ - refs_->IncRefCount(); - refs_->SetCallback(std::bind(&RefBase::RefPtrCallback, this)); + return refCount > 0; } RefBase::RefBase(const RefBase &) @@ -402,11 +394,23 @@ RefBase::RefBase(const RefBase &) } } +RefBase::RefBase() : refs_(new RefCounter()) +{ + refs_->IncRefCount(); + refs_->SetCallback(std::bind(&RefBase::RefPtrCallback, this)); +} + void RefBase::RefPtrCallback() { delete this; } +RefBase::RefBase(RefBase &&other) noexcept +{ + refs_ = other.refs_; + other.refs_ = nullptr; +} + /* * The two ends of the assignment are two independent and exclusive, * and the application should not share the reference counter. @@ -419,33 +423,23 @@ RefBase &RefBase::operator=(const RefBase &) refs_->RemoveCallback(); refs_->DecRefCount(); } - refs_ = new (std::nothrow) RefCounter(); if (refs_ != nullptr) { refs_->IncRefCount(); refs_->SetCallback(std::bind(&RefBase::RefPtrCallback, this)); } - return *this; } -RefBase::RefBase(RefBase &&other) noexcept -{ - refs_ = other.refs_; - other.refs_ = nullptr; -} - RefBase &RefBase::operator=(RefBase &&other) noexcept { if (refs_ == other.refs_) { return *this; } - if (refs_ != nullptr) { refs_->RemoveCallback(); refs_->DecRefCount(); } - refs_ = other.refs_; other.refs_ = nullptr; return *this; @@ -459,15 +453,11 @@ RefBase::~RefBase() refs_->GetStrongRefCount() == INITIAL_PRIMARY_VALUE) { refs_->DecRefCount(); } + refs_ = nullptr; } } -void RefBase::ExtendObjectLifetime() -{ - refs_->ExtendObjectLifetime(); -} - void RefBase::IncStrongRef(const void *objectId) { if (refs_ == nullptr) { @@ -475,13 +465,14 @@ void RefBase::IncStrongRef(const void *objectId) } IncWeakRef(objectId); - const int curCount = refs_->IncStrongRefCount(objectId); - if (!refs_->IsLifeTimeExtended() && curCount == 0) { + const int refCount = refs_->IncStrongRefCount(objectId); + if (!refs_->IsLifeTimeExtended() && refCount == 0) { UTILS_LOGF("%{public}p still incStrongRef after last strong ref", this); } - if (curCount == INITIAL_PRIMARY_VALUE) { + if (refCount == INITIAL_PRIMARY_VALUE) { OnFirstStrongRef(objectId); } + if (refs_->IsAttemptAcquireSet()) { refs_->ClearAttemptAcquire(); refs_->DecStrongRefCount(objectId); @@ -489,6 +480,11 @@ void RefBase::IncStrongRef(const void *objectId) } } +void RefBase::ExtendObjectLifetime() +{ + refs_->ExtendObjectLifetime(); +} + void RefBase::DecStrongRef(const void *objectId) { if (refs_ == nullptr) { @@ -496,11 +492,12 @@ void RefBase::DecStrongRef(const void *objectId) } RefCounter * const refs = refs_; - const int curCount = refs->DecStrongRefCount(objectId); - if (curCount <= 0) { + const int refCount = refs->DecStrongRefCount(objectId); + if (refCount <= 0) { UTILS_LOGF("%{public}p call decStrongRef too many times", this); } - if (curCount == 1) { + + if (refCount == 1) { std::atomic_thread_fence(std::memory_order_acquire); OnLastStrongRef(objectId); if (!refs->IsLifeTimeExtended()) { @@ -513,14 +510,6 @@ void RefBase::DecStrongRef(const void *objectId) refs->DecWeakRefCount(objectId); } -int RefBase::GetSptrRefCount() -{ - if (refs_ == nullptr) { - return 0; - } - return refs_->GetStrongRefCount(); -} - WeakRefCounter *RefBase::CreateWeakRef(void *cookie) { if (refs_ != nullptr) { @@ -529,16 +518,19 @@ WeakRefCounter *RefBase::CreateWeakRef(void *cookie) return nullptr; } -void RefBase::IncWeakRef(const void *objectId) +int RefBase::GetSptrRefCount() { - if (refs_ != nullptr) { - refs_->IncWeakRefCount(objectId); + if (refs_ == nullptr) { + return 0; } + return refs_->GetStrongRefCount(); } -RefCounter *RefBase::GetRefCounter() const +void RefBase::IncWeakRef(const void *objectId) { - return refs_; + if (refs_ != nullptr) { + refs_->IncWeakRefCount(objectId); + } } void RefBase::DecWeakRef(const void *objectId) @@ -556,45 +548,35 @@ int RefBase::GetWptrRefCount() return refs_->GetWeakRefCount(); } -bool RefBase::AttemptAcquire(const void *objectId) +RefCounter *RefBase::GetRefCounter() const { - if (refs_ == nullptr) { - return false; - } - - int count = 0; - if (refs_->AttemptIncStrongRef(objectId, count)) { - refs_->SetAttemptAcquire(); - if (count == INITIAL_PRIMARY_VALUE) { - OnFirstStrongRef(objectId); - } - - return true; - } - return false; + return refs_; } bool RefBase::AttemptIncStrongRef(const void *objectId) { if ((refs_ != nullptr) && (OnAttemptPromoted(objectId))) { - int count = 0; - bool ret = refs_->AttemptIncStrongRef(objectId, count); - if (count == INITIAL_PRIMARY_VALUE) { + int refCount = 0; + bool ret = refs_->AttemptIncStrongRef(objectId, refCount); + if (refCount == INITIAL_PRIMARY_VALUE) { OnFirstStrongRef(objectId); } return ret; } - return false; } -bool RefBase::AttemptIncStrong(const void *objectId) +bool RefBase::AttemptAcquire(const void *objectId) { if (refs_ == nullptr) { return false; } - if (refs_->AttemptIncStrong(objectId)) { + int refCount = 0; + if (refs_->AttemptIncStrongRef(objectId, refCount)) { refs_->SetAttemptAcquire(); + if (refCount == INITIAL_PRIMARY_VALUE) { + OnFirstStrongRef(objectId); + } return true; } return false; @@ -608,6 +590,19 @@ bool RefBase::IsAttemptAcquireSet() return refs_->IsAttemptAcquireSet(); } +bool RefBase::AttemptIncStrong(const void *objectId) +{ + if (refs_ == nullptr) { + return false; + } + + if (refs_->AttemptIncStrong(objectId)) { + refs_->SetAttemptAcquire(); + return true; + } + return false; +} + bool RefBase::IsExtendLifeTimeSet() { if (refs_ == nullptr) { @@ -616,20 +611,15 @@ bool RefBase::IsExtendLifeTimeSet() return refs_->IsLifeTimeExtended(); } -void RefBase::OnFirstStrongRef(const void*) +void RefBase::OnLastStrongRef(const void*) {} -void RefBase::OnLastStrongRef(const void*) +void RefBase::OnFirstStrongRef(const void*) {} void RefBase::OnLastWeakRef(const void*) {} -bool RefBase::OnAttemptPromoted(const void*) -{ - return true; -} - #if ((defined DEBUG_REFBASE) && (!defined TRACK_ALL)) void RefBase::EnableTracker() { @@ -641,4 +631,9 @@ void RefBase::EnableTracker() } #endif +bool RefBase::OnAttemptPromoted(const void*) +{ + return true; +} + } // namespace OHOS