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