13f4cbf05Sopenharmony_ci/* 23f4cbf05Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License. 53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at 63f4cbf05Sopenharmony_ci * 73f4cbf05Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83f4cbf05Sopenharmony_ci * 93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and 133f4cbf05Sopenharmony_ci * limitations under the License. 143f4cbf05Sopenharmony_ci */ 153f4cbf05Sopenharmony_ci 163f4cbf05Sopenharmony_ci#include "refbase_fuzzer.h" 173f4cbf05Sopenharmony_ci 183f4cbf05Sopenharmony_ci#include <thread> 193f4cbf05Sopenharmony_ci#include <vector> 203f4cbf05Sopenharmony_ci 213f4cbf05Sopenharmony_ci#include "fuzz_log.h" 223f4cbf05Sopenharmony_ci#include "fuzzer/FuzzedDataProvider.h" 233f4cbf05Sopenharmony_ci#include "refbase.h" 243f4cbf05Sopenharmony_ci#include "rwlock.h" 253f4cbf05Sopenharmony_ci 263f4cbf05Sopenharmony_ciusing namespace std; 273f4cbf05Sopenharmony_ci 283f4cbf05Sopenharmony_cinamespace OHOS { 293f4cbf05Sopenharmony_ciconst int MAX_THREADS = 10; 303f4cbf05Sopenharmony_ciconst int MAX_OPS = 200; 313f4cbf05Sopenharmony_ciconst int SLEEP_NANO_SECONDS = 10; 323f4cbf05Sopenharmony_ci 333f4cbf05Sopenharmony_ciuint32_t GetThreadId() 343f4cbf05Sopenharmony_ci{ 353f4cbf05Sopenharmony_ci std::thread::id tid = this_thread::get_id(); 363f4cbf05Sopenharmony_ci return *reinterpret_cast<uint32_t*>(&tid); 373f4cbf05Sopenharmony_ci} 383f4cbf05Sopenharmony_ci 393f4cbf05Sopenharmony_cistruct TestRefBase : public RefBase { 403f4cbf05Sopenharmony_cipublic: 413f4cbf05Sopenharmony_ci TestRefBase(bool* deleted, Utils::RWLock& rwLock) : deleted_(deleted), rwLock_(rwLock) 423f4cbf05Sopenharmony_ci { 433f4cbf05Sopenharmony_ci rwLock_.LockWrite(); 443f4cbf05Sopenharmony_ci *deleted_ = false; 453f4cbf05Sopenharmony_ci rwLock_.UnLockWrite(); 463f4cbf05Sopenharmony_ci ExtendObjectLifetime(); 473f4cbf05Sopenharmony_ci } 483f4cbf05Sopenharmony_ci 493f4cbf05Sopenharmony_ci virtual ~TestRefBase() 503f4cbf05Sopenharmony_ci { 513f4cbf05Sopenharmony_ci rwLock_.LockWrite(); 523f4cbf05Sopenharmony_ci *deleted_ = true; 533f4cbf05Sopenharmony_ci rwLock_.UnLockWrite(); 543f4cbf05Sopenharmony_ci } 553f4cbf05Sopenharmony_ci 563f4cbf05Sopenharmony_ci void OnLastStrongRef(const void* objectId) override; 573f4cbf05Sopenharmony_ci void OnFirstStrongRef(const void* objectId) override; 583f4cbf05Sopenharmony_ci 593f4cbf05Sopenharmony_ciprivate: 603f4cbf05Sopenharmony_ci bool* deleted_; 613f4cbf05Sopenharmony_ci Utils::RWLock& rwLock_; 623f4cbf05Sopenharmony_ci}; 633f4cbf05Sopenharmony_ci 643f4cbf05Sopenharmony_civoid TestRefBase::OnLastStrongRef(const void* objectId) 653f4cbf05Sopenharmony_ci{ 663f4cbf05Sopenharmony_ci std::this_thread::sleep_for(std::chrono::nanoseconds(SLEEP_NANO_SECONDS)); 673f4cbf05Sopenharmony_ci} 683f4cbf05Sopenharmony_ci 693f4cbf05Sopenharmony_civoid TestRefBase::OnFirstStrongRef(const void* objectId) 703f4cbf05Sopenharmony_ci{ 713f4cbf05Sopenharmony_ci std::this_thread::sleep_for(std::chrono::nanoseconds(SLEEP_NANO_SECONDS)); 723f4cbf05Sopenharmony_ci} 733f4cbf05Sopenharmony_ci 743f4cbf05Sopenharmony_cistruct SingleThreadRefCounts { 753f4cbf05Sopenharmony_ci size_t strongCount = 0; 763f4cbf05Sopenharmony_ci size_t weakCount = 0; 773f4cbf05Sopenharmony_ci bool weakRefCounterExists = false; 783f4cbf05Sopenharmony_ci size_t weakRefCount = 0; 793f4cbf05Sopenharmony_ci}; 803f4cbf05Sopenharmony_ci 813f4cbf05Sopenharmony_ciTestRefBase* g_ref; 823f4cbf05Sopenharmony_cibool g_refModified = false; 833f4cbf05Sopenharmony_cibool g_refDeleted = false; 843f4cbf05Sopenharmony_ciUtils::RWLock g_deletedLock; 853f4cbf05Sopenharmony_ciUtils::RWLock g_strongLock; 863f4cbf05Sopenharmony_ciUtils::RWLock g_attemptLock; 873f4cbf05Sopenharmony_ci 883f4cbf05Sopenharmony_ciconst std::vector<std::function<void(SingleThreadRefCounts*, WeakRefCounter*&)>> decOperations = { 893f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*&) { 903f4cbf05Sopenharmony_ci if (refState->strongCount > 0) { 913f4cbf05Sopenharmony_ci refState->strongCount--; 923f4cbf05Sopenharmony_ci bool shouldLock = refState->strongCount == 0 && refState->weakCount == 0 && refState->weakRefCount == 0; 933f4cbf05Sopenharmony_ci if (shouldLock) { 943f4cbf05Sopenharmony_ci g_strongLock.LockWrite(); 953f4cbf05Sopenharmony_ci } 963f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, DecStrongRef, refState->strongCount = %{public}zu", GetThreadId(), 973f4cbf05Sopenharmony_ci refState->strongCount); 983f4cbf05Sopenharmony_ci g_ref->DecStrongRef(nullptr); 993f4cbf05Sopenharmony_ci if (shouldLock) { 1003f4cbf05Sopenharmony_ci g_strongLock.UnLockWrite(); 1013f4cbf05Sopenharmony_ci } 1023f4cbf05Sopenharmony_ci g_refModified = true; 1033f4cbf05Sopenharmony_ci } 1043f4cbf05Sopenharmony_ci }, 1053f4cbf05Sopenharmony_ci 1063f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*& weakRef) { 1073f4cbf05Sopenharmony_ci if (refState->weakRefCount > 0) { 1083f4cbf05Sopenharmony_ci refState->weakRefCount--; 1093f4cbf05Sopenharmony_ci refState->weakRefCounterExists = refState->weakRefCount > 0; 1103f4cbf05Sopenharmony_ci bool shouldLock = refState->strongCount == 0 && refState->weakCount == 0 && refState->weakRefCount == 0; 1113f4cbf05Sopenharmony_ci if (shouldLock) { 1123f4cbf05Sopenharmony_ci g_strongLock.LockWrite(); 1133f4cbf05Sopenharmony_ci } 1143f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, weakRef->DecWeakRefCount, refState->weakRefCount = %{public}zu", 1153f4cbf05Sopenharmony_ci GetThreadId(), refState->weakRefCount); 1163f4cbf05Sopenharmony_ci weakRef->DecWeakRefCount(nullptr); 1173f4cbf05Sopenharmony_ci if (shouldLock) { 1183f4cbf05Sopenharmony_ci g_strongLock.UnLockWrite(); 1193f4cbf05Sopenharmony_ci } 1203f4cbf05Sopenharmony_ci g_refModified = true; 1213f4cbf05Sopenharmony_ci } 1223f4cbf05Sopenharmony_ci }, 1233f4cbf05Sopenharmony_ci 1243f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*&) { 1253f4cbf05Sopenharmony_ci if (refState->weakCount > 0) { 1263f4cbf05Sopenharmony_ci refState->weakCount--; 1273f4cbf05Sopenharmony_ci bool shouldLock = refState->strongCount == 0 && refState->weakCount == 0 && refState->weakRefCount == 0; 1283f4cbf05Sopenharmony_ci if (shouldLock) { 1293f4cbf05Sopenharmony_ci g_strongLock.LockWrite(); 1303f4cbf05Sopenharmony_ci } 1313f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, DecWeakRef, refState->weakCount = %{public}zu", GetThreadId(), 1323f4cbf05Sopenharmony_ci refState->weakCount); 1333f4cbf05Sopenharmony_ci g_ref->DecWeakRef(nullptr); 1343f4cbf05Sopenharmony_ci if (shouldLock) { 1353f4cbf05Sopenharmony_ci g_strongLock.UnLockWrite(); 1363f4cbf05Sopenharmony_ci } 1373f4cbf05Sopenharmony_ci g_refModified = true; 1383f4cbf05Sopenharmony_ci } 1393f4cbf05Sopenharmony_ci }, 1403f4cbf05Sopenharmony_ci}; 1413f4cbf05Sopenharmony_ci 1423f4cbf05Sopenharmony_ciconst std::vector<std::function<void(SingleThreadRefCounts*, WeakRefCounter*&)>> readOrIncOperations = { 1433f4cbf05Sopenharmony_ci [](SingleThreadRefCounts*, WeakRefCounter*&) { 1443f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, GetSptrRefCount", GetThreadId()); 1453f4cbf05Sopenharmony_ci g_ref->GetSptrRefCount(); 1463f4cbf05Sopenharmony_ci }, 1473f4cbf05Sopenharmony_ci 1483f4cbf05Sopenharmony_ci [](SingleThreadRefCounts*, WeakRefCounter*&) { 1493f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, GetRefCounter", GetThreadId()); 1503f4cbf05Sopenharmony_ci RefCounter* refCounter = g_ref->GetRefCounter(); 1513f4cbf05Sopenharmony_ci if (refCounter != nullptr) { 1523f4cbf05Sopenharmony_ci refCounter->GetRefCount(); 1533f4cbf05Sopenharmony_ci } 1543f4cbf05Sopenharmony_ci }, 1553f4cbf05Sopenharmony_ci 1563f4cbf05Sopenharmony_ci [](SingleThreadRefCounts*, WeakRefCounter*&) { 1573f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, GetWptrRefCount", GetThreadId()); 1583f4cbf05Sopenharmony_ci g_ref->GetWptrRefCount(); 1593f4cbf05Sopenharmony_ci }, 1603f4cbf05Sopenharmony_ci 1613f4cbf05Sopenharmony_ci [](SingleThreadRefCounts*, WeakRefCounter*&) { 1623f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, IsAttemptAcquireSet", GetThreadId()); 1633f4cbf05Sopenharmony_ci g_ref->IsAttemptAcquireSet(); 1643f4cbf05Sopenharmony_ci }, 1653f4cbf05Sopenharmony_ci 1663f4cbf05Sopenharmony_ci [](SingleThreadRefCounts*, WeakRefCounter*&) { 1673f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, IsExtendLifeTimeSet", GetThreadId()); 1683f4cbf05Sopenharmony_ci g_ref->IsExtendLifeTimeSet(); 1693f4cbf05Sopenharmony_ci }, 1703f4cbf05Sopenharmony_ci 1713f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*& weakRef) { 1723f4cbf05Sopenharmony_ci if (refState->weakRefCounterExists) { 1733f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, weakRef->GetWeakRefCount", GetThreadId()); 1743f4cbf05Sopenharmony_ci weakRef->GetWeakRefCount(); 1753f4cbf05Sopenharmony_ci } 1763f4cbf05Sopenharmony_ci }, 1773f4cbf05Sopenharmony_ci 1783f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*&) { 1793f4cbf05Sopenharmony_ci g_attemptLock.LockRead(); 1803f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, IncStrongRef", GetThreadId()); 1813f4cbf05Sopenharmony_ci g_ref->IncStrongRef(nullptr); 1823f4cbf05Sopenharmony_ci refState->strongCount++; 1833f4cbf05Sopenharmony_ci g_refModified = true; 1843f4cbf05Sopenharmony_ci g_attemptLock.UnLockRead(); 1853f4cbf05Sopenharmony_ci }, 1863f4cbf05Sopenharmony_ci 1873f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*& weakRef) { 1883f4cbf05Sopenharmony_ci if (!refState->weakRefCounterExists) { 1893f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, CreateWeakRef", GetThreadId()); 1903f4cbf05Sopenharmony_ci weakRef = g_ref->CreateWeakRef(nullptr); 1913f4cbf05Sopenharmony_ci refState->weakRefCounterExists = true; 1923f4cbf05Sopenharmony_ci // Only CreateWeakRef then release, will not delete RefBase, so g_refModified will not change. 1933f4cbf05Sopenharmony_ci } 1943f4cbf05Sopenharmony_ci }, 1953f4cbf05Sopenharmony_ci 1963f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*& weakRef) { 1973f4cbf05Sopenharmony_ci if (refState->weakRefCounterExists) { 1983f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, weakRef->IncWeakRefCount", GetThreadId()); 1993f4cbf05Sopenharmony_ci weakRef->IncWeakRefCount(nullptr); 2003f4cbf05Sopenharmony_ci refState->weakRefCount++; 2013f4cbf05Sopenharmony_ci g_refModified = true; 2023f4cbf05Sopenharmony_ci } 2033f4cbf05Sopenharmony_ci }, 2043f4cbf05Sopenharmony_ci 2053f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*& weakRef) { 2063f4cbf05Sopenharmony_ci if (refState->weakRefCounterExists) { 2073f4cbf05Sopenharmony_ci g_attemptLock.LockWrite(); 2083f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, weakRef->AttemptIncStrongRef", GetThreadId()); 2093f4cbf05Sopenharmony_ci weakRef->AttemptIncStrongRef(nullptr); 2103f4cbf05Sopenharmony_ci refState->strongCount++; 2113f4cbf05Sopenharmony_ci g_refModified = true; 2123f4cbf05Sopenharmony_ci g_attemptLock.UnLockWrite(); 2133f4cbf05Sopenharmony_ci } 2143f4cbf05Sopenharmony_ci }, 2153f4cbf05Sopenharmony_ci 2163f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*&) { 2173f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, IncWeakRef", GetThreadId()); 2183f4cbf05Sopenharmony_ci g_ref->IncWeakRef(nullptr); 2193f4cbf05Sopenharmony_ci refState->weakCount++; 2203f4cbf05Sopenharmony_ci g_refModified = true; 2213f4cbf05Sopenharmony_ci }, 2223f4cbf05Sopenharmony_ci 2233f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*&) { 2243f4cbf05Sopenharmony_ci g_attemptLock.LockWrite(); 2253f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, AttemptAcquire", GetThreadId()); 2263f4cbf05Sopenharmony_ci g_ref->AttemptAcquire(nullptr); 2273f4cbf05Sopenharmony_ci g_ref->IncStrongRef(nullptr); 2283f4cbf05Sopenharmony_ci refState->strongCount++; 2293f4cbf05Sopenharmony_ci g_refModified = true; 2303f4cbf05Sopenharmony_ci g_attemptLock.UnLockWrite(); 2313f4cbf05Sopenharmony_ci }, 2323f4cbf05Sopenharmony_ci 2333f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*&) { 2343f4cbf05Sopenharmony_ci g_attemptLock.LockWrite(); 2353f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, AttemptIncStrongRef", GetThreadId()); 2363f4cbf05Sopenharmony_ci g_ref->AttemptIncStrongRef(nullptr); 2373f4cbf05Sopenharmony_ci refState->strongCount++; 2383f4cbf05Sopenharmony_ci g_refModified = true; 2393f4cbf05Sopenharmony_ci g_attemptLock.UnLockWrite(); 2403f4cbf05Sopenharmony_ci }, 2413f4cbf05Sopenharmony_ci 2423f4cbf05Sopenharmony_ci [](SingleThreadRefCounts* refState, WeakRefCounter*&) { 2433f4cbf05Sopenharmony_ci g_attemptLock.LockWrite(); 2443f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, AttemptIncStrong", GetThreadId()); 2453f4cbf05Sopenharmony_ci g_ref->AttemptIncStrong(nullptr); 2463f4cbf05Sopenharmony_ci g_ref->IncStrongRef(nullptr); 2473f4cbf05Sopenharmony_ci refState->strongCount++; 2483f4cbf05Sopenharmony_ci g_refModified = true; 2493f4cbf05Sopenharmony_ci g_attemptLock.UnLockWrite(); 2503f4cbf05Sopenharmony_ci }, 2513f4cbf05Sopenharmony_ci}; 2523f4cbf05Sopenharmony_ci 2533f4cbf05Sopenharmony_ci// Clean up WeakRefCounter 2543f4cbf05Sopenharmony_civoid CleanUpWeakRefCounter(SingleThreadRefCounts& state, WeakRefCounter* newWeakRef) 2553f4cbf05Sopenharmony_ci{ 2563f4cbf05Sopenharmony_ci if (state.weakRefCounterExists) { 2573f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, delete newWeakRef", GetThreadId()); 2583f4cbf05Sopenharmony_ci delete newWeakRef; 2593f4cbf05Sopenharmony_ci } else if (state.weakRefCount > 0) { 2603f4cbf05Sopenharmony_ci for (; state.weakRefCount > 0; --state.weakRefCount) { 2613f4cbf05Sopenharmony_ci bool shouldLock = state.strongCount == 0 && state.weakCount == 0 && state.weakRefCount == 0; 2623f4cbf05Sopenharmony_ci if (shouldLock) { 2633f4cbf05Sopenharmony_ci g_strongLock.LockWrite(); 2643f4cbf05Sopenharmony_ci } 2653f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, clean up DecWeakRefCount, refState->weakRefCount = %{public}zu", 2663f4cbf05Sopenharmony_ci GetThreadId(), state.weakRefCount); 2673f4cbf05Sopenharmony_ci newWeakRef->DecWeakRefCount(nullptr); 2683f4cbf05Sopenharmony_ci if (shouldLock) { 2693f4cbf05Sopenharmony_ci g_strongLock.UnLockWrite(); 2703f4cbf05Sopenharmony_ci } 2713f4cbf05Sopenharmony_ci } 2723f4cbf05Sopenharmony_ci } 2733f4cbf05Sopenharmony_ci} 2743f4cbf05Sopenharmony_ci 2753f4cbf05Sopenharmony_ci// Clean up any weak references 2763f4cbf05Sopenharmony_civoid CleanUpWeakCounter(SingleThreadRefCounts& state) 2773f4cbf05Sopenharmony_ci{ 2783f4cbf05Sopenharmony_ci for (; state.weakCount > 0; state.weakCount--) { 2793f4cbf05Sopenharmony_ci bool shouldLock = state.strongCount == 0 && state.weakCount == 1; 2803f4cbf05Sopenharmony_ci if (shouldLock) { 2813f4cbf05Sopenharmony_ci g_strongLock.LockWrite(); 2823f4cbf05Sopenharmony_ci } 2833f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, clean up DecWeakRef, refState->weakCount = %{public}zu", GetThreadId(), 2843f4cbf05Sopenharmony_ci state.weakCount - 1); 2853f4cbf05Sopenharmony_ci g_ref->DecWeakRef(nullptr); 2863f4cbf05Sopenharmony_ci if (shouldLock) { 2873f4cbf05Sopenharmony_ci g_strongLock.UnLockWrite(); 2883f4cbf05Sopenharmony_ci } 2893f4cbf05Sopenharmony_ci } 2903f4cbf05Sopenharmony_ci} 2913f4cbf05Sopenharmony_ci 2923f4cbf05Sopenharmony_ci// Clean up any strong references 2933f4cbf05Sopenharmony_civoid CleanUpStrongCounter(SingleThreadRefCounts& state) 2943f4cbf05Sopenharmony_ci{ 2953f4cbf05Sopenharmony_ci for (; state.strongCount > 0; state.strongCount--) { 2963f4cbf05Sopenharmony_ci bool shouldLock = state.strongCount == 1; 2973f4cbf05Sopenharmony_ci if (shouldLock) { 2983f4cbf05Sopenharmony_ci g_strongLock.LockWrite(); 2993f4cbf05Sopenharmony_ci } 3003f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, clean up DecStrongRef, refState->strongCount = %{public}zu", GetThreadId(), 3013f4cbf05Sopenharmony_ci state.strongCount - 1); 3023f4cbf05Sopenharmony_ci g_ref->DecStrongRef(nullptr); 3033f4cbf05Sopenharmony_ci if (shouldLock) { 3043f4cbf05Sopenharmony_ci g_strongLock.UnLockWrite(); 3053f4cbf05Sopenharmony_ci } 3063f4cbf05Sopenharmony_ci } 3073f4cbf05Sopenharmony_ci} 3083f4cbf05Sopenharmony_ci 3093f4cbf05Sopenharmony_civoid TestLoop(const std::vector<uint8_t>& fuzzOps) 3103f4cbf05Sopenharmony_ci{ 3113f4cbf05Sopenharmony_ci SingleThreadRefCounts state; 3123f4cbf05Sopenharmony_ci uint8_t lockedOpSize = readOrIncOperations.size(); 3133f4cbf05Sopenharmony_ci uint8_t totalOperationTypes = lockedOpSize + decOperations.size(); 3143f4cbf05Sopenharmony_ci WeakRefCounter* newWeakRef = nullptr; 3153f4cbf05Sopenharmony_ci 3163f4cbf05Sopenharmony_ci for (auto op : fuzzOps) { 3173f4cbf05Sopenharmony_ci auto opVal = op % totalOperationTypes; 3183f4cbf05Sopenharmony_ci if (opVal >= lockedOpSize) { 3193f4cbf05Sopenharmony_ci decOperations[opVal % lockedOpSize](&state, newWeakRef); 3203f4cbf05Sopenharmony_ci } else { 3213f4cbf05Sopenharmony_ci bool shouldLock = state.strongCount == 0 && state.weakCount == 0 && state.weakRefCount == 0; 3223f4cbf05Sopenharmony_ci if (shouldLock) { 3233f4cbf05Sopenharmony_ci g_strongLock.LockRead(); 3243f4cbf05Sopenharmony_ci if (g_refDeleted) { 3253f4cbf05Sopenharmony_ci if (state.weakRefCounterExists) { 3263f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u, delete newWeakRef", GetThreadId()); 3273f4cbf05Sopenharmony_ci delete newWeakRef; 3283f4cbf05Sopenharmony_ci } 3293f4cbf05Sopenharmony_ci FUZZ_LOGI("thread = %{public}u return", GetThreadId()); 3303f4cbf05Sopenharmony_ci g_strongLock.UnLockRead(); 3313f4cbf05Sopenharmony_ci return; 3323f4cbf05Sopenharmony_ci } 3333f4cbf05Sopenharmony_ci } 3343f4cbf05Sopenharmony_ci readOrIncOperations[opVal](&state, newWeakRef); 3353f4cbf05Sopenharmony_ci if (shouldLock) { 3363f4cbf05Sopenharmony_ci g_strongLock.UnLockRead(); 3373f4cbf05Sopenharmony_ci } 3383f4cbf05Sopenharmony_ci } 3393f4cbf05Sopenharmony_ci } 3403f4cbf05Sopenharmony_ci 3413f4cbf05Sopenharmony_ci CleanUpWeakRefCounter(state, newWeakRef); 3423f4cbf05Sopenharmony_ci CleanUpWeakCounter(state); 3433f4cbf05Sopenharmony_ci CleanUpStrongCounter(state); 3443f4cbf05Sopenharmony_ci} 3453f4cbf05Sopenharmony_ci 3463f4cbf05Sopenharmony_civoid RefbaseTestFunc(const uint8_t* data, size_t size, FuzzedDataProvider* dataProvider) 3473f4cbf05Sopenharmony_ci{ 3483f4cbf05Sopenharmony_ci FUZZ_LOGI("RefbaseTestFunc start"); 3493f4cbf05Sopenharmony_ci g_ref = new TestRefBase(&g_refDeleted, g_deletedLock); 3503f4cbf05Sopenharmony_ci g_refModified = false; 3513f4cbf05Sopenharmony_ci uint8_t threadNum = 1; 3523f4cbf05Sopenharmony_ci vector<thread> threads = vector<thread>(); 3533f4cbf05Sopenharmony_ci threadNum = dataProvider->ConsumeIntegralInRange<uint8_t>(1, MAX_THREADS); 3543f4cbf05Sopenharmony_ci 3553f4cbf05Sopenharmony_ci for (uint8_t i = 0; i < threadNum; i++) { 3563f4cbf05Sopenharmony_ci uint8_t opsSize = 1; 3573f4cbf05Sopenharmony_ci opsSize = dataProvider->ConsumeIntegralInRange<uint8_t>(1, MAX_OPS); 3583f4cbf05Sopenharmony_ci vector<uint8_t> ops = dataProvider->ConsumeBytes<uint8_t>(opsSize); 3593f4cbf05Sopenharmony_ci thread threadTmp = thread(TestLoop, ops); 3603f4cbf05Sopenharmony_ci threads.push_back(move(threadTmp)); 3613f4cbf05Sopenharmony_ci } 3623f4cbf05Sopenharmony_ci 3633f4cbf05Sopenharmony_ci for (thread& th : threads) { 3643f4cbf05Sopenharmony_ci th.join(); 3653f4cbf05Sopenharmony_ci } 3663f4cbf05Sopenharmony_ci 3673f4cbf05Sopenharmony_ci if (!g_refModified && !g_refDeleted) { 3683f4cbf05Sopenharmony_ci delete g_ref; 3693f4cbf05Sopenharmony_ci g_ref = nullptr; 3703f4cbf05Sopenharmony_ci } 3713f4cbf05Sopenharmony_ci FUZZ_LOGI("RefbaseTestFunc end"); 3723f4cbf05Sopenharmony_ci} 3733f4cbf05Sopenharmony_ci 3743f4cbf05Sopenharmony_ci} // namespace OHOS 3753f4cbf05Sopenharmony_ci 3763f4cbf05Sopenharmony_ci/* Fuzzer entry point */ 3773f4cbf05Sopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 3783f4cbf05Sopenharmony_ci{ 3793f4cbf05Sopenharmony_ci FuzzedDataProvider dataProvider(data, size); 3803f4cbf05Sopenharmony_ci OHOS::RefbaseTestFunc(data, size, &dataProvider); 3813f4cbf05Sopenharmony_ci return 0; 3823f4cbf05Sopenharmony_ci} 383