From 78875ad248af660b9a57863e7506da1e9b500c80 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Fri, 10 Jan 2025 18:09:43 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0log=E6=89=93=E5=8D=B0Doma?= =?UTF-8?q?inID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yp9522 Change-Id: Id2c0d2c00859eeddf1dc70a6c8ed478d24d1f95f --- base/include/refbase.h | 18 +++- base/src/refbase.cpp | 101 +++++++++++++++--- base/src/utils_log.h | 1 + .../unittest/common/utils_refbase_test.cpp | 90 ++++++++++++++++ 4 files changed, 194 insertions(+), 16 deletions(-) diff --git a/base/include/refbase.h b/base/include/refbase.h index 089fc4b..68fb082 100644 --- a/base/include/refbase.h +++ b/base/include/refbase.h @@ -257,9 +257,19 @@ public: void EnableTracker(); #endif +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + /** + * @brief Enables tracking with domainId. It is applicable to debugging only. + */ + void EnableTrackerWithDomainId(unsigned int domainId); +#endif + private: void DebugRefBase(const void *objectId); + void RefBaseDebugPrint(int curCount, const void* caller, const void* objectId, + const char* operation, const char* countType); + std::atomic atomicStrong_; // = (num of sptr) or Initial-value std::atomic atomicWeak_; // = (num of sptr)+(num of WeakRefCounter) std::atomic atomicRefCount_; // = (num of WeakRefCounter) + 1 @@ -278,7 +288,7 @@ private: #endif std::mutex trackerMutex; // To ensure refTracker be thread-safe #ifdef PRINT_TRACK_AT_ONCE - void PrintRefs(const void* objectId); + unsigned int domainId_ = 0xD003D00; #else RefTracker* refTracker = nullptr; void GetNewTrace(const void* objectId); @@ -595,6 +605,12 @@ public: */ void EnableTracker(); + /** + * @brief Enables tracking of the RefBase object with domainId. This function will + * be implemented only if DEBUG_REFBASE, but not TRACK_ALL, is defined. + */ + void EnableTrackerWithDomainId(unsigned int domainId); + #ifdef OHOS_PLATFORM virtual bool CanPromote(); #endif diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index a39676c..11d4c21 100644 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -21,6 +21,21 @@ namespace OHOS { +void RefCounter::RefBaseDebugPrint([[maybe_unused]] int curCount, + [[maybe_unused]] const void* caller, + [[maybe_unused]] const void* objectId, + [[maybe_unused]] const char* operation, + [[maybe_unused]] const char* countType) +{ +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + if (this->enableTrack) { + UTILS_LOGT(this->domainId_, "curCount: %{public}d, caller: %{public}p, " + "objectId: %{public}p, operation: %{public}s, countType: %{public}s, this: %{public}p", \ + curCount, caller, objectId, operation, countType, (void*)this); + } +#endif +} + WeakRefCounter::WeakRefCounter(RefCounter *counter, void *cookie) : atomicWeak_(0), refCounter_(counter), cookie_(cookie) { @@ -118,12 +133,11 @@ RefTracker* RefTracker::PopTrace(const void* refCounterPtr) #ifdef DEBUG_REFBASE #ifdef PRINT_TRACK_AT_ONCE -void RefCounter::PrintRefs(const void* objectId) +void RefCounter::EnableTrackerWithDomainId(unsigned int domainId) { std::lock_guard lock(trackerMutex); - UTILS_LOGI("%{public}p call %{public}p. strong: %{public}d weak: %{public}d " \ - "refcnt: %{public}d", objectId, this, atomicStrong_.load(std::memory_order_relaxed), - atomicWeak_.load(std::memory_order_relaxed), atomicRefCount_.load(std::memory_order_relaxed)); + this->domainId_ = domainId; + enableTrack = true; } #else void RefCounter::GetNewTrace(const void* objectId) @@ -151,21 +165,19 @@ void RefCounter::PrintTracker() void RefCounter::EnableTracker() { std::lock_guard lock(trackerMutex); -#ifdef PRINT_TRACK_AT_ONCE - UTILS_LOGI("%{public}p start tracking", this); -#endif +#ifndef PRINT_TRACK_AT_ONCE enableTrack = true; +#endif } #endif + #endif void RefCounter::DebugRefBase([[maybe_unused]]const void* objectId) { #ifdef DEBUG_REFBASE if (enableTrack) { -#ifdef PRINT_TRACK_AT_ONCE - PrintRefs(objectId); -#else +#ifndef PRINT_TRACK_AT_ONCE GetNewTrace(objectId); #endif } @@ -184,13 +196,22 @@ int RefCounter::GetRefCount() void RefCounter::IncRefCount() { +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + int curCount = atomicRefCount_.fetch_add(1, std::memory_order_relaxed); + RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "++", "atomicRefCount_"); +#else atomicRefCount_.fetch_add(1, std::memory_order_relaxed); +#endif } void RefCounter::DecRefCount() { if (atomicRefCount_.load(std::memory_order_relaxed) > 0) { - if (atomicRefCount_.fetch_sub(1, std::memory_order_release) == 1) { + int curCount = atomicRefCount_.fetch_sub(1, std::memory_order_release); +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "++", "atomicRefCount_"); +#endif + if (curCount == 1) { delete (this); } } @@ -232,9 +253,7 @@ RefCounter::~RefCounter() { #ifdef DEBUG_REFBASE if (enableTrack) { -#ifdef PRINT_TRACK_AT_ONCE - UTILS_LOGI("%{public}p end tracking", this); -#else +#ifndef PRINT_TRACK_AT_ONCE PrintTracker(); #endif } @@ -247,8 +266,16 @@ int RefCounter::IncStrongRefCount(const void* objectId) int curCount = atomicStrong_.load(std::memory_order_relaxed); if (curCount >= 0) { curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); +#endif if (curCount == INITIAL_PRIMARY_VALUE) { +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + int newCurCount = atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release); + RefBaseDebugPrint(newCurCount, __builtin_return_address(0), objectId, "--", "atomicStrong_"); +#else atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release); +#endif } } @@ -266,6 +293,9 @@ int RefCounter::DecStrongRefCount(const void* objectId) // we should update the current count here. // it may be changed after last operation. curCount = atomicStrong_.fetch_sub(1, std::memory_order_release); +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "--", "atomicStrong_"); +#endif } return curCount; @@ -279,7 +309,11 @@ int RefCounter::GetStrongRefCount() int RefCounter::IncWeakRefCount(const void* objectId) { DebugRefBase(objectId); - return atomicWeak_.fetch_add(1, std::memory_order_relaxed); + int curCount = atomicWeak_.fetch_add(1, std::memory_order_relaxed); +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicWeak_"); +#endif + return curCount; } int RefCounter::DecWeakRefCount(const void* objectId) @@ -288,6 +322,9 @@ int RefCounter::DecWeakRefCount(const void* objectId) int curCount = GetWeakRefCount(); if (curCount > 0) { curCount = atomicWeak_.fetch_sub(1, std::memory_order_release); +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "--", "atomicWeak_"); +#endif } if (curCount != 1) { @@ -326,7 +363,12 @@ int RefCounter::GetAttemptAcquire() void RefCounter::SetAttemptAcquire() { +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + int curCount = atomicAttempt_.fetch_add(1, std::memory_order_relaxed); + RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "++", "atomicAttempt_"); +#else (void)atomicAttempt_.fetch_add(1, std::memory_order_relaxed); +#endif } bool RefCounter::IsAttemptAcquireSet() @@ -336,7 +378,12 @@ bool RefCounter::IsAttemptAcquireSet() void RefCounter::ClearAttemptAcquire() { +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + int curCount = atomicAttempt_.fetch_sub(1, std::memory_order_relaxed); + RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "--", "atomicAttempt_"); +#else atomicAttempt_.fetch_sub(1, std::memory_order_relaxed); +#endif } void RefCounter::ExtendObjectLifetime() @@ -357,6 +404,9 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) // 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)) { +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); +#endif goto ATTEMPT_SUCCESS; } // someone else changed the counter.re-acquire the counter value. @@ -367,6 +417,9 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) // this object has a "normal" life-time, while (curCount > 0) { if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) { +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); +#endif goto ATTEMPT_SUCCESS; } curCount = atomicStrong_.load(std::memory_order_relaxed); @@ -380,12 +433,20 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) } #endif curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); +#endif } ATTEMPT_SUCCESS: if (curCount == INITIAL_PRIMARY_VALUE) { outCount = curCount; +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + int newCurCount = atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release); + RefBaseDebugPrint(newCurCount, __builtin_return_address(0), objectId, "--", "atomicStrong_"); +#else atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release); +#endif return true; } @@ -404,6 +465,9 @@ bool RefCounter::AttemptIncStrong(const void *objectId) int curCount = GetStrongRefCount(); while (curCount > 0) { if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) { +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); +#endif break; } // curCount has been updated. @@ -693,4 +757,11 @@ void RefBase::EnableTracker() } #endif +void RefBase::EnableTrackerWithDomainId(unsigned int domainId) +{ +#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) + refs_->EnableTrackerWithDomainId(domainId); +#endif +} + } // namespace OHOS diff --git a/base/src/utils_log.h b/base/src/utils_log.h index 1b3efac..4e186e5 100644 --- a/base/src/utils_log.h +++ b/base/src/utils_log.h @@ -24,6 +24,7 @@ constexpr const char *UTILS_LOG_TAG = "utils_base"; #define UTILS_LOGE(...) (void)HiLogBasePrint(UTILS_LOG_TYPE, LOG_ERROR, UTILS_LOG_DOMAIN, UTILS_LOG_TAG, __VA_ARGS__) #define UTILS_LOGW(...) (void)HiLogBasePrint(UTILS_LOG_TYPE, LOG_WARN, UTILS_LOG_DOMAIN, UTILS_LOG_TAG, __VA_ARGS__) #define UTILS_LOGI(...) (void)HiLogBasePrint(UTILS_LOG_TYPE, LOG_INFO, UTILS_LOG_DOMAIN, UTILS_LOG_TAG, __VA_ARGS__) +#define UTILS_LOGT(DOMAIN, ...) (void)HiLogBasePrint(UTILS_LOG_TYPE, LOG_DEBUG, DOMAIN, UTILS_LOG_TAG, __VA_ARGS__) #ifdef DEBUG_UTILS #define UTILS_LOGD(...) (void)HiLogBasePrint(UTILS_LOG_TYPE, LOG_DEBUG, UTILS_LOG_DOMAIN, UTILS_LOG_TAG, __VA_ARGS__) #else diff --git a/base/test/unittest/common/utils_refbase_test.cpp b/base/test/unittest/common/utils_refbase_test.cpp index b620880..272fb36 100644 --- a/base/test/unittest/common/utils_refbase_test.cpp +++ b/base/test/unittest/common/utils_refbase_test.cpp @@ -1157,6 +1157,44 @@ HWTEST_F(UtilsRefbaseTest, testRefbaseDebug002, TestSize.Level1) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } +/* + * @tc.name: testRefbaseWithDomainIdDebug001 + * @tc.desc: Test for single thread. Tracker can be enabled after construction + * of sptr. + */ +HWTEST_F(UtilsRefbaseTest, testRefbaseWithDomainIdDebug001, TestSize.Level1) +{ + sptr testObject1(new RefBase()); + testObject1->EnableTrackerWithDomainId(0xD001651); + sptr testObject2(testObject1); + EXPECT_EQ(testObject2->GetSptrRefCount(), 2); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr testObject3(testObject2); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr testObject4(testObject3); + EXPECT_EQ(testObject4->GetWptrRefCount(), 3); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); +} + +/* + * @tc.name: testRefbaseWithDomainIdDebug002 + * @tc.desc: Test for single thread. Tracker can be enabled after construction + * of wptr. + */ +HWTEST_F(UtilsRefbaseTest, testRefbaseWithDomainIdDebug002, TestSize.Level1) +{ + wptr testObject1(new RefBase()); + testObject1->EnableTrackerWithDomainId(0xD001651); + sptr testObject2 = testObject1.promote(); + EXPECT_EQ(testObject2->GetSptrRefCount(), 1); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr testObject3(testObject2); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr testObject4(testObject3); + EXPECT_EQ(testObject4->GetWptrRefCount(), 3); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); +} + // This is a class which can be tracked when implemented. class TestDebug : public RefBase { public: @@ -1166,6 +1204,14 @@ public: } }; +class TestDebugWithDomainId : public RefBase { +public: + TestDebugWithDomainId() + { + EnableTrackerWithDomainId(0xD001651); + } +}; + /* * @tc.name: testRefbaseDebug003 * @tc.desc: Test for single thread. Tracker can be enabled with construction @@ -1209,5 +1255,49 @@ HWTEST_F(UtilsRefbaseTest, testRefbaseDebug004, TestSize.Level1) subThread.join(); EXPECT_EQ(testObject3->GetWptrRefCount(), 2); } + +/* + * @tc.name: testRefbaseWithDomainIdDebug003 + * @tc.desc: Test for single thread. Tracker can be enabled with construction + * of sptr. + */ +HWTEST_F(UtilsRefbaseTest, testRefbaseWithDomainIdDebug003, TestSize.Level1) +{ + sptr testObject1(new TestDebugWithDomainId()); + sptr testObject2(testObject1); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + sptr testObject3; + EXPECT_EQ(testObject2->GetSptrRefCount(), 2); + testObject3 = testObject2; + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr testObject4(testObject3); + EXPECT_EQ(testObject4->GetWptrRefCount(), 4); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); +} + +/* + * @tc.name: testRefbaseWithDomainIdDebug004 + * @tc.desc: Test for mult-thread. + */ +HWTEST_F(UtilsRefbaseTest, testRefbaseWithDomainIdDebug004, TestSize.Level1) +{ + sptr testObject1(new TestDebugWithDomainId()); + std::thread subThread {[&testObject1]() { + sptr subTestObject1(testObject1); + EXPECT_EQ(testObject1->GetSptrRefCount(), 2); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr subTestObject2(subTestObject1); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr subTestObject3(subTestObject2); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + }}; + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr testObject2(testObject1); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + wptr testObject3(testObject2); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + subThread.join(); + EXPECT_EQ(testObject3->GetWptrRefCount(), 2); +} } // namespace } // namespace OHOS -- Gitee From efc589052d16c0ea31154366c0427984cb9927d2 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Tue, 14 Jan 2025 14:23:20 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yp9522 Change-Id: I254c02770ddd2bfbf13518ea9964d9af788993d1 --- base/src/refbase.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index 11d4c21..dff37bc 100644 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -437,7 +437,6 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); #endif } - ATTEMPT_SUCCESS: if (curCount == INITIAL_PRIMARY_VALUE) { outCount = curCount; -- Gitee From f0532091d2b9368aec6238a132ebbbfe236dae36 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Tue, 14 Jan 2025 14:47:31 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yp9522 Change-Id: Ib91d7c0cf7776e7cebd8d5f148a1a4bf066d0910 --- base/src/refbase.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index dff37bc..c83a7b5 100644 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -400,7 +400,6 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) { int curCount = 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)) { @@ -454,7 +453,6 @@ ATTEMPT_SUCCESS: DecWeakRefCount(objectId); return false; } - return true; } -- Gitee From 964d38d7974e8588733a2e80a15a282edb6101af Mon Sep 17 00:00:00 2001 From: yp9522 Date: Tue, 14 Jan 2025 15:12:36 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yp9522 Change-Id: I98964206970c6106dde4c79d47129403e1ed50d6 --- base/src/refbase.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index c83a7b5..f39a306 100644 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -403,9 +403,7 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) // 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)) { -#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); -#endif goto ATTEMPT_SUCCESS; } // someone else changed the counter.re-acquire the counter value. @@ -416,9 +414,7 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) // this object has a "normal" life-time, while (curCount > 0) { if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) { -#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); -#endif goto ATTEMPT_SUCCESS; } curCount = atomicStrong_.load(std::memory_order_relaxed); @@ -432,9 +428,7 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) } #endif curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); -#if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE)) RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_"); -#endif } ATTEMPT_SUCCESS: if (curCount == INITIAL_PRIMARY_VALUE) { -- Gitee