1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#include <mutex>
17484543d1Sopenharmony_ci#include <future>
18484543d1Sopenharmony_ci#include <chrono>
19484543d1Sopenharmony_ci#include <random>
20484543d1Sopenharmony_ci#include <gtest/gtest.h>
21484543d1Sopenharmony_ci#include "sync/sync.h"
22484543d1Sopenharmony_ci#include "ffrt_inner.h"
23484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h"
24484543d1Sopenharmony_ci#include "c/thread.h"
25484543d1Sopenharmony_ci#include "c/ffrt_ipc.h"
26484543d1Sopenharmony_ci#include "tm/cpu_task.h"
27484543d1Sopenharmony_ci#include "../common.h"
28484543d1Sopenharmony_ci
29484543d1Sopenharmony_ciextern "C" int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
30484543d1Sopenharmony_ciextern "C" int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
31484543d1Sopenharmony_ciextern "C" int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
32484543d1Sopenharmony_ciextern "C" int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
33484543d1Sopenharmony_ciextern "C" int ffrt_mutex_init(ffrt_mutex_t *mutex, const ffrt_mutexattr_t* attr);
34484543d1Sopenharmony_ciextern "C" int ffrt_mutex_lock(ffrt_mutex_t *mutex);
35484543d1Sopenharmony_ciextern "C" int ffrt_mutex_unlock(ffrt_mutex_t *mutex);
36484543d1Sopenharmony_ciextern "C" int ffrt_mutex_trylock(ffrt_mutex_t *mutex);
37484543d1Sopenharmony_ciextern "C" int ffrt_mutex_destroy(ffrt_mutex_t *mutex);
38484543d1Sopenharmony_ci
39484543d1Sopenharmony_ciusing namespace std;
40484543d1Sopenharmony_ciusing namespace testing;
41484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE
42484543d1Sopenharmony_ciusing namespace testing::ext;
43484543d1Sopenharmony_ci#endif
44484543d1Sopenharmony_ci
45484543d1Sopenharmony_ciclass SyncTest : public testing::Test {
46484543d1Sopenharmony_ciprotected:
47484543d1Sopenharmony_ci    static void SetUpTestCase()
48484543d1Sopenharmony_ci    {
49484543d1Sopenharmony_ci    }
50484543d1Sopenharmony_ci
51484543d1Sopenharmony_ci    static void TearDownTestCase()
52484543d1Sopenharmony_ci    {
53484543d1Sopenharmony_ci    }
54484543d1Sopenharmony_ci
55484543d1Sopenharmony_ci    virtual void SetUp()
56484543d1Sopenharmony_ci    {
57484543d1Sopenharmony_ci    }
58484543d1Sopenharmony_ci
59484543d1Sopenharmony_ci    virtual void TearDown()
60484543d1Sopenharmony_ci    {
61484543d1Sopenharmony_ci    }
62484543d1Sopenharmony_ci};
63484543d1Sopenharmony_ci
64484543d1Sopenharmony_ci/**
65484543d1Sopenharmony_ci * @tc.name: mutexattr_nullptr_fail
66484543d1Sopenharmony_ci * @tc.desc: Test function of mutexattr when the input is nullptr;
67484543d1Sopenharmony_ci * @tc.type: FUNC
68484543d1Sopenharmony_ci */
69484543d1Sopenharmony_ciHWTEST_F(SyncTest, mutexattr_nullptr_fail, TestSize.Level1)
70484543d1Sopenharmony_ci{
71484543d1Sopenharmony_ci    int ret = ffrt_mutexattr_init(nullptr);
72484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
73484543d1Sopenharmony_ci    ret = ffrt_mutexattr_settype(nullptr, 0);
74484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
75484543d1Sopenharmony_ci    ret = ffrt_mutexattr_gettype(nullptr, nullptr);
76484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
77484543d1Sopenharmony_ci    ret = ffrt_mutexattr_destroy(nullptr);
78484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
79484543d1Sopenharmony_ci}
80484543d1Sopenharmony_ci
81484543d1Sopenharmony_ci/**
82484543d1Sopenharmony_ci * @tc.name: mutex_nullptr_fail
83484543d1Sopenharmony_ci * @tc.desc: Test function of mutex when the input is nullptr;
84484543d1Sopenharmony_ci * @tc.type: FUNC
85484543d1Sopenharmony_ci */
86484543d1Sopenharmony_ciHWTEST_F(SyncTest, mutex_nullptr_fail, TestSize.Level1)
87484543d1Sopenharmony_ci{
88484543d1Sopenharmony_ci    int ret = ffrt_mutex_init(nullptr, nullptr);
89484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
90484543d1Sopenharmony_ci    ret = ffrt_mutex_lock(nullptr);
91484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
92484543d1Sopenharmony_ci    ret = ffrt_mutex_unlock(nullptr);
93484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
94484543d1Sopenharmony_ci    ret = ffrt_mutex_trylock(nullptr);
95484543d1Sopenharmony_ci    EXPECT_EQ(ret, ffrt_error_inval);
96484543d1Sopenharmony_ci    ffrt_mutex_destroy(nullptr);
97484543d1Sopenharmony_ci}
98484543d1Sopenharmony_ci
99484543d1Sopenharmony_ci/**
100484543d1Sopenharmony_ci * @tc.name: mutex_try_lock
101484543d1Sopenharmony_ci * @tc.desc: Test function of mutex:try_lock
102484543d1Sopenharmony_ci * @tc.type: FUNC
103484543d1Sopenharmony_ci */
104484543d1Sopenharmony_ciHWTEST_F(SyncTest, mutex_try_lock, TestSize.Level1)
105484543d1Sopenharmony_ci{
106484543d1Sopenharmony_ci    int val = -1;
107484543d1Sopenharmony_ci    ffrt::mutex lock;
108484543d1Sopenharmony_ci    lock.lock();
109484543d1Sopenharmony_ci    val = lock.try_lock();
110484543d1Sopenharmony_ci    EXPECT_EQ(val, 0);
111484543d1Sopenharmony_ci    lock.unlock();
112484543d1Sopenharmony_ci    val = lock.try_lock();
113484543d1Sopenharmony_ci    EXPECT_EQ(val, 1);
114484543d1Sopenharmony_ci    lock.unlock();
115484543d1Sopenharmony_ci    lock.unlock();
116484543d1Sopenharmony_ci}
117484543d1Sopenharmony_ci
118484543d1Sopenharmony_ci/**
119484543d1Sopenharmony_ci * @tc.name: recursive_mutex_try_lock
120484543d1Sopenharmony_ci * @tc.desc: Test function of recursive mutex:try_lock
121484543d1Sopenharmony_ci * @tc.type: FUNC
122484543d1Sopenharmony_ci */
123484543d1Sopenharmony_ciHWTEST_F(SyncTest, recursive_mutex_try_lock, TestSize.Level1)
124484543d1Sopenharmony_ci{
125484543d1Sopenharmony_ci    int val = -1;
126484543d1Sopenharmony_ci    ffrt::recursive_mutex lock;
127484543d1Sopenharmony_ci    lock.lock();
128484543d1Sopenharmony_ci    val = lock.try_lock();
129484543d1Sopenharmony_ci    EXPECT_EQ(val, 1);
130484543d1Sopenharmony_ci    lock.unlock();
131484543d1Sopenharmony_ci    val = lock.try_lock();
132484543d1Sopenharmony_ci    EXPECT_EQ(val, 1);
133484543d1Sopenharmony_ci    lock.unlock();
134484543d1Sopenharmony_ci    lock.unlock();
135484543d1Sopenharmony_ci}
136484543d1Sopenharmony_ci
137484543d1Sopenharmony_ci/**
138484543d1Sopenharmony_ci * @tc.name: mutex_lock_with_BlockThread
139484543d1Sopenharmony_ci * @tc.desc: Test function of mutex:lock in Thread mode
140484543d1Sopenharmony_ci * @tc.type: FUNC
141484543d1Sopenharmony_ci */
142484543d1Sopenharmony_ciHWTEST_F(SyncTest, mutex_lock_with_BlockThread, TestSize.Level1)
143484543d1Sopenharmony_ci{
144484543d1Sopenharmony_ci    int x = 0;
145484543d1Sopenharmony_ci    ffrt::mutex lock;
146484543d1Sopenharmony_ci    ffrt::submit([&]() {
147484543d1Sopenharmony_ci        ffrt::this_task::sleep_for(10ms);
148484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(true);
149484543d1Sopenharmony_ci        lock.lock();
150484543d1Sopenharmony_ci        ffrt::submit([&]() {
151484543d1Sopenharmony_ci            EXPECT_EQ(x, 1);
152484543d1Sopenharmony_ci            }, {&x}, {});
153484543d1Sopenharmony_ci        ffrt::submit([&]() {
154484543d1Sopenharmony_ci            x++;
155484543d1Sopenharmony_ci            EXPECT_EQ(x, 2);
156484543d1Sopenharmony_ci            }, {&x}, {&x});
157484543d1Sopenharmony_ci        ffrt::submit([&]() {
158484543d1Sopenharmony_ci            EXPECT_EQ(x, 2);
159484543d1Sopenharmony_ci            }, {&x}, {});
160484543d1Sopenharmony_ci        ffrt::wait();
161484543d1Sopenharmony_ci        lock.unlock();
162484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(false);
163484543d1Sopenharmony_ci        }, {}, {}, ffrt::task_attr().name("t2"));
164484543d1Sopenharmony_ci
165484543d1Sopenharmony_ci    ffrt::submit([&]() {
166484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(true);
167484543d1Sopenharmony_ci        lock.lock();
168484543d1Sopenharmony_ci        ffrt::submit([&]() {
169484543d1Sopenharmony_ci            EXPECT_EQ(x, 0);
170484543d1Sopenharmony_ci            }, {&x}, {});
171484543d1Sopenharmony_ci        ffrt::submit([&]() {
172484543d1Sopenharmony_ci            x++;
173484543d1Sopenharmony_ci            EXPECT_EQ(x, 1);
174484543d1Sopenharmony_ci            }, {&x}, {&x});
175484543d1Sopenharmony_ci        ffrt::submit([&]() {
176484543d1Sopenharmony_ci            EXPECT_EQ(x, 1);
177484543d1Sopenharmony_ci            }, {&x}, {});
178484543d1Sopenharmony_ci        ffrt::wait();
179484543d1Sopenharmony_ci        lock.unlock();
180484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(false);
181484543d1Sopenharmony_ci        }, {}, {}, ffrt::task_attr().name("t1"));
182484543d1Sopenharmony_ci    ffrt::wait();
183484543d1Sopenharmony_ci}
184484543d1Sopenharmony_ci
185484543d1Sopenharmony_ci/**
186484543d1Sopenharmony_ci * @tc.name: shared_mutex_lock_with_BlockThread
187484543d1Sopenharmony_ci * @tc.desc: Test function of shared mutex:lock in Thread mode
188484543d1Sopenharmony_ci * @tc.type: FUNC
189484543d1Sopenharmony_ci */
190484543d1Sopenharmony_ciHWTEST_F(SyncTest, shared_mutex_lock_with_BlockThread, TestSize.Level1)
191484543d1Sopenharmony_ci{
192484543d1Sopenharmony_ci    int x = 0;
193484543d1Sopenharmony_ci    const int N = 10;
194484543d1Sopenharmony_ci    ffrt::shared_mutex lock;
195484543d1Sopenharmony_ci    for (int i = 0; i < N; ++i) {
196484543d1Sopenharmony_ci        ffrt::submit([&]() {
197484543d1Sopenharmony_ci            ffrt_this_task_set_legacy_mode(true);
198484543d1Sopenharmony_ci            lock.lock();
199484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(10ms);
200484543d1Sopenharmony_ci            x++;
201484543d1Sopenharmony_ci            lock.unlock();
202484543d1Sopenharmony_ci            ffrt_this_task_set_legacy_mode(false);
203484543d1Sopenharmony_ci            }, {}, {}, ffrt::task_attr().name("t1"));
204484543d1Sopenharmony_ci    }
205484543d1Sopenharmony_ci    ffrt::submit([&]() {
206484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(true);
207484543d1Sopenharmony_ci        lock.lock();
208484543d1Sopenharmony_ci        printf("x is %d", x);
209484543d1Sopenharmony_ci        lock.unlock();
210484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(false);
211484543d1Sopenharmony_ci        }, {}, {}, ffrt::task_attr().name("t2"));
212484543d1Sopenharmony_ci
213484543d1Sopenharmony_ci    ffrt::wait();
214484543d1Sopenharmony_ci}
215484543d1Sopenharmony_ci
216484543d1Sopenharmony_ci/**
217484543d1Sopenharmony_ci * @tc.name: set_legacy_mode_within_nested_task
218484543d1Sopenharmony_ci * @tc.desc: Test function of mutex:lock in Thread mode
219484543d1Sopenharmony_ci * @tc.type: FUNC
220484543d1Sopenharmony_ci */
221484543d1Sopenharmony_ciHWTEST_F(SyncTest, set_legacy_mode_within_nested_task, TestSize.Level1)
222484543d1Sopenharmony_ci{
223484543d1Sopenharmony_ci    int x = 0;
224484543d1Sopenharmony_ci    ffrt::submit([&]() {
225484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(true);
226484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(true);
227484543d1Sopenharmony_ci        ffrt::CPUEUTask* ctx = ffrt::ExecuteCtx::Cur()->task;
228484543d1Sopenharmony_ci        bool result = ffrt::LegacyMode(ctx);
229484543d1Sopenharmony_ci        EXPECT_EQ(result, 1);
230484543d1Sopenharmony_ci        ffrt::submit([&]() {
231484543d1Sopenharmony_ci            ffrt_this_task_set_legacy_mode(true);
232484543d1Sopenharmony_ci            ffrt::CPUEUTask* ctx = ffrt::ExecuteCtx::Cur()->task;
233484543d1Sopenharmony_ci            bool result = ffrt::LegacyMode(ctx);
234484543d1Sopenharmony_ci            EXPECT_EQ(result, 1);
235484543d1Sopenharmony_ci            x++;
236484543d1Sopenharmony_ci            EXPECT_EQ(x, 1);
237484543d1Sopenharmony_ci            ffrt_this_task_set_legacy_mode(false);
238484543d1Sopenharmony_ci            ffrt_this_task_set_legacy_mode(false);
239484543d1Sopenharmony_ci            ctx = ffrt::ExecuteCtx::Cur()->task;
240484543d1Sopenharmony_ci            int legacycount = ctx->legacyCountNum;
241484543d1Sopenharmony_ci            EXPECT_EQ(legacycount, -1);
242484543d1Sopenharmony_ci            }, {}, {});
243484543d1Sopenharmony_ci        ffrt::wait();
244484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(false);
245484543d1Sopenharmony_ci        ffrt_this_task_set_legacy_mode(false);
246484543d1Sopenharmony_ci        ctx = ffrt::ExecuteCtx::Cur()->task;
247484543d1Sopenharmony_ci        int legacycount = ctx->legacyCountNum;
248484543d1Sopenharmony_ci        EXPECT_EQ(legacycount, 0);
249484543d1Sopenharmony_ci        }, {}, {});
250484543d1Sopenharmony_ci    ffrt::wait();
251484543d1Sopenharmony_ci    EXPECT_EQ(x, 1);
252484543d1Sopenharmony_ci}
253484543d1Sopenharmony_ci
254484543d1Sopenharmony_ciHWTEST_F(SyncTest, class_data_align, TestSize.Level1)
255484543d1Sopenharmony_ci{
256484543d1Sopenharmony_ci    struct memTest {
257484543d1Sopenharmony_ci        bool isFlag; // Construct an unaligned address
258484543d1Sopenharmony_ci        ffrt::mutex mtx;
259484543d1Sopenharmony_ci        ffrt::task_attr taskAttr;
260484543d1Sopenharmony_ci        ffrt::task_handle taskHandle;
261484543d1Sopenharmony_ci        ffrt::condition_variable cv;
262484543d1Sopenharmony_ci        ffrt::thread t;
263484543d1Sopenharmony_ci    };
264484543d1Sopenharmony_ci    memTest m;
265484543d1Sopenharmony_ci    {
266484543d1Sopenharmony_ci        ffrt::mutex* mtxAddr = &m.mtx;
267484543d1Sopenharmony_ci        uintptr_t addr_int = reinterpret_cast<uintptr_t>(mtxAddr);
268484543d1Sopenharmony_ci        EXPECT_EQ((addr_int % 4), 0);
269484543d1Sopenharmony_ci
270484543d1Sopenharmony_ci        ffrt::task_attr* attrAddr = &m.taskAttr;
271484543d1Sopenharmony_ci        addr_int = reinterpret_cast<uintptr_t>(attrAddr);
272484543d1Sopenharmony_ci        EXPECT_EQ((addr_int % 4), 0);
273484543d1Sopenharmony_ci
274484543d1Sopenharmony_ci        ffrt::task_handle* handleAddr = &m.taskHandle;
275484543d1Sopenharmony_ci        addr_int = reinterpret_cast<uintptr_t>(handleAddr);
276484543d1Sopenharmony_ci        EXPECT_EQ((addr_int % 4), 0);
277484543d1Sopenharmony_ci
278484543d1Sopenharmony_ci        ffrt::condition_variable* cvAddr = &m.cv;
279484543d1Sopenharmony_ci        addr_int = reinterpret_cast<uintptr_t>(cvAddr);
280484543d1Sopenharmony_ci        EXPECT_EQ((addr_int % 4), 0);
281484543d1Sopenharmony_ci
282484543d1Sopenharmony_ci        ffrt::thread* tAddr = &m.t;
283484543d1Sopenharmony_ci        addr_int = reinterpret_cast<uintptr_t>(tAddr);
284484543d1Sopenharmony_ci        EXPECT_EQ((addr_int % 4), 0);
285484543d1Sopenharmony_ci    }
286484543d1Sopenharmony_ci}
287484543d1Sopenharmony_ci
288484543d1Sopenharmony_ciHWTEST_F(SyncTest, lock_stress, TestSize.Level1)
289484543d1Sopenharmony_ci{
290484543d1Sopenharmony_ci    // trigger lazy init
291484543d1Sopenharmony_ci    ffrt::submit([&]() {}, {}, {});
292484543d1Sopenharmony_ci    ffrt::wait();
293484543d1Sopenharmony_ci
294484543d1Sopenharmony_ci    const int N = 10;
295484543d1Sopenharmony_ci    const int M = 1000;
296484543d1Sopenharmony_ci    const int J = 10000;
297484543d1Sopenharmony_ci    ffrt::mutex lock;
298484543d1Sopenharmony_ci    // std::mutex lock;
299484543d1Sopenharmony_ci    int acc = 0;
300484543d1Sopenharmony_ci    for (int i = 0; i < N; ++i) {
301484543d1Sopenharmony_ci        ffrt::submit(
302484543d1Sopenharmony_ci            [&]() {
303484543d1Sopenharmony_ci                for (int j = 0; j < M; ++j) {
304484543d1Sopenharmony_ci                    lock.lock();
305484543d1Sopenharmony_ci                    acc++;
306484543d1Sopenharmony_ci                    lock.unlock();
307484543d1Sopenharmony_ci                }
308484543d1Sopenharmony_ci            },
309484543d1Sopenharmony_ci            {}, {});
310484543d1Sopenharmony_ci    }
311484543d1Sopenharmony_ci
312484543d1Sopenharmony_ci    for (int j = 0; j < J; ++j) {
313484543d1Sopenharmony_ci        lock.lock();
314484543d1Sopenharmony_ci        acc++;
315484543d1Sopenharmony_ci        lock.unlock();
316484543d1Sopenharmony_ci    }
317484543d1Sopenharmony_ci
318484543d1Sopenharmony_ci    ffrt::wait();
319484543d1Sopenharmony_ci    EXPECT_EQ(acc, (M * N + J));
320484543d1Sopenharmony_ci}
321484543d1Sopenharmony_ci
322484543d1Sopenharmony_ciHWTEST_F(SyncTest, lock_stress_c_api, TestSize.Level1)
323484543d1Sopenharmony_ci{
324484543d1Sopenharmony_ci    // trigger lazy init
325484543d1Sopenharmony_ci    ffrt::submit([&]() {}, {}, {});
326484543d1Sopenharmony_ci    ffrt::wait();
327484543d1Sopenharmony_ci
328484543d1Sopenharmony_ci    const int N = 10;
329484543d1Sopenharmony_ci    const int M = 1000;
330484543d1Sopenharmony_ci    const int J = 10000;
331484543d1Sopenharmony_ci    ffrt::mutex* lock = new ffrt::mutex;
332484543d1Sopenharmony_ci    int acc = 0;
333484543d1Sopenharmony_ci    for (int i = 0; i < N; ++i) {
334484543d1Sopenharmony_ci        ffrt::submit(
335484543d1Sopenharmony_ci            [&]() {
336484543d1Sopenharmony_ci                for (int j = 0; j < M; ++j) {
337484543d1Sopenharmony_ci                    lock->lock();
338484543d1Sopenharmony_ci                    acc++;
339484543d1Sopenharmony_ci                    lock->unlock();
340484543d1Sopenharmony_ci                }
341484543d1Sopenharmony_ci            },
342484543d1Sopenharmony_ci            {}, {});
343484543d1Sopenharmony_ci    }
344484543d1Sopenharmony_ci
345484543d1Sopenharmony_ci    for (int j = 0; j < J; ++j) {
346484543d1Sopenharmony_ci        lock->lock();
347484543d1Sopenharmony_ci        acc++;
348484543d1Sopenharmony_ci        lock->unlock();
349484543d1Sopenharmony_ci    }
350484543d1Sopenharmony_ci
351484543d1Sopenharmony_ci    ffrt::wait();
352484543d1Sopenharmony_ci    EXPECT_EQ(acc, (M * N + J));
353484543d1Sopenharmony_ci    delete lock;
354484543d1Sopenharmony_ci}
355484543d1Sopenharmony_ci
356484543d1Sopenharmony_ci/**
357484543d1Sopenharmony_ci * @tc.name: recursive_lock_stress
358484543d1Sopenharmony_ci * @tc.desc: Test C++ function of recursive mutex:lock in stress mode
359484543d1Sopenharmony_ci * @tc.type: FUNC
360484543d1Sopenharmony_ci */
361484543d1Sopenharmony_ciHWTEST_F(SyncTest, recursive_lock_stress, TestSize.Level1)
362484543d1Sopenharmony_ci{
363484543d1Sopenharmony_ci    // trigger lazy init
364484543d1Sopenharmony_ci    ffrt::submit([&]() {}, {}, {});
365484543d1Sopenharmony_ci    ffrt::wait();
366484543d1Sopenharmony_ci
367484543d1Sopenharmony_ci    const int N = 10;
368484543d1Sopenharmony_ci    const int M = 1000;
369484543d1Sopenharmony_ci    const int J = 10000;
370484543d1Sopenharmony_ci    ffrt::recursive_mutex lock;
371484543d1Sopenharmony_ci    // std::mutex lock;
372484543d1Sopenharmony_ci    int acc = 0;
373484543d1Sopenharmony_ci    for (int i = 0; i < N; ++i) {
374484543d1Sopenharmony_ci        ffrt::submit(
375484543d1Sopenharmony_ci            [&]() {
376484543d1Sopenharmony_ci                for (int j = 0; j < M; ++j) {
377484543d1Sopenharmony_ci                    lock.lock();
378484543d1Sopenharmony_ci                    acc++;
379484543d1Sopenharmony_ci                    lock.unlock();
380484543d1Sopenharmony_ci                }
381484543d1Sopenharmony_ci            },
382484543d1Sopenharmony_ci            {}, {});
383484543d1Sopenharmony_ci    }
384484543d1Sopenharmony_ci
385484543d1Sopenharmony_ci    for (int j = 0; j < J; ++j) {
386484543d1Sopenharmony_ci        lock.lock();
387484543d1Sopenharmony_ci        acc++;
388484543d1Sopenharmony_ci        lock.unlock();
389484543d1Sopenharmony_ci    }
390484543d1Sopenharmony_ci
391484543d1Sopenharmony_ci    ffrt::wait();
392484543d1Sopenharmony_ci    EXPECT_EQ(acc, (M * N + J));
393484543d1Sopenharmony_ci}
394484543d1Sopenharmony_ci
395484543d1Sopenharmony_ci/**
396484543d1Sopenharmony_ci * @tc.name: recursive_lock_stress
397484543d1Sopenharmony_ci * @tc.desc: Test C function of recursive mutex:lock in stress mode
398484543d1Sopenharmony_ci * @tc.type: FUNC
399484543d1Sopenharmony_ci */
400484543d1Sopenharmony_ciHWTEST_F(SyncTest, recursive_lock_stress_c_api, TestSize.Level1)
401484543d1Sopenharmony_ci{
402484543d1Sopenharmony_ci    // trigger lazy init
403484543d1Sopenharmony_ci    ffrt::submit([&]() {}, {}, {});
404484543d1Sopenharmony_ci    ffrt::wait();
405484543d1Sopenharmony_ci
406484543d1Sopenharmony_ci    const int N = 10;
407484543d1Sopenharmony_ci    const int M = 1000;
408484543d1Sopenharmony_ci    const int J = 10000;
409484543d1Sopenharmony_ci    ffrt::recursive_mutex* lock = new ffrt::recursive_mutex;
410484543d1Sopenharmony_ci    int acc = 0;
411484543d1Sopenharmony_ci    for (int i = 0; i < N; ++i) {
412484543d1Sopenharmony_ci        ffrt::submit(
413484543d1Sopenharmony_ci            [&]() {
414484543d1Sopenharmony_ci                for (int j = 0; j < M; ++j) {
415484543d1Sopenharmony_ci                    lock->lock();
416484543d1Sopenharmony_ci                    acc++;
417484543d1Sopenharmony_ci                    lock->unlock();
418484543d1Sopenharmony_ci                }
419484543d1Sopenharmony_ci            },
420484543d1Sopenharmony_ci            {}, {});
421484543d1Sopenharmony_ci    }
422484543d1Sopenharmony_ci
423484543d1Sopenharmony_ci    for (int j = 0; j < J; ++j) {
424484543d1Sopenharmony_ci        lock->lock();
425484543d1Sopenharmony_ci        acc++;
426484543d1Sopenharmony_ci        lock->unlock();
427484543d1Sopenharmony_ci    }
428484543d1Sopenharmony_ci
429484543d1Sopenharmony_ci    ffrt::wait();
430484543d1Sopenharmony_ci    EXPECT_EQ(acc, (M * N + J));
431484543d1Sopenharmony_ci    delete lock;
432484543d1Sopenharmony_ci}
433484543d1Sopenharmony_ci
434484543d1Sopenharmony_ciHWTEST_F(SyncTest, conditionTestNotifyOne, TestSize.Level1)
435484543d1Sopenharmony_ci{
436484543d1Sopenharmony_ci    ffrt::condition_variable cond;
437484543d1Sopenharmony_ci    int a = 0;
438484543d1Sopenharmony_ci    ffrt::mutex lock_;
439484543d1Sopenharmony_ci
440484543d1Sopenharmony_ci    ffrt::submit(
441484543d1Sopenharmony_ci        [&]() {
442484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
443484543d1Sopenharmony_ci            cond.wait(lck, [&] { return a == 1; });
444484543d1Sopenharmony_ci        },
445484543d1Sopenharmony_ci        {}, {});
446484543d1Sopenharmony_ci
447484543d1Sopenharmony_ci    ffrt::submit(
448484543d1Sopenharmony_ci        [&]() {
449484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
450484543d1Sopenharmony_ci            a = 1;
451484543d1Sopenharmony_ci            cond.notify_one();
452484543d1Sopenharmony_ci        },
453484543d1Sopenharmony_ci        {}, {});
454484543d1Sopenharmony_ci    ffrt::wait();
455484543d1Sopenharmony_ci}
456484543d1Sopenharmony_ci
457484543d1Sopenharmony_ciHWTEST_F(SyncTest, conditionTestNotifyAll, TestSize.Level1)
458484543d1Sopenharmony_ci{
459484543d1Sopenharmony_ci    ffrt::condition_variable cond;
460484543d1Sopenharmony_ci    int a = 0;
461484543d1Sopenharmony_ci    ffrt::mutex lock_;
462484543d1Sopenharmony_ci
463484543d1Sopenharmony_ci    ffrt::submit(
464484543d1Sopenharmony_ci        [&]() {
465484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
466484543d1Sopenharmony_ci            cond.wait(lck, [&] { return a == 1; });
467484543d1Sopenharmony_ci        },
468484543d1Sopenharmony_ci        {}, {});
469484543d1Sopenharmony_ci    ffrt::submit(
470484543d1Sopenharmony_ci        [&]() {
471484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
472484543d1Sopenharmony_ci            cond.wait(lck, [&] { return a == 1; });
473484543d1Sopenharmony_ci        },
474484543d1Sopenharmony_ci        {}, {});
475484543d1Sopenharmony_ci    ffrt::submit(
476484543d1Sopenharmony_ci        [&]() {
477484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
478484543d1Sopenharmony_ci            cond.wait(lck, [&] { return a == 1; });
479484543d1Sopenharmony_ci        },
480484543d1Sopenharmony_ci        {}, {});
481484543d1Sopenharmony_ci
482484543d1Sopenharmony_ci    ffrt::submit(
483484543d1Sopenharmony_ci        [&]() {
484484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
485484543d1Sopenharmony_ci            a = 1;
486484543d1Sopenharmony_ci            cond.notify_all();
487484543d1Sopenharmony_ci        },
488484543d1Sopenharmony_ci        {}, {});
489484543d1Sopenharmony_ci    ffrt::wait();
490484543d1Sopenharmony_ci}
491484543d1Sopenharmony_ci
492484543d1Sopenharmony_ciHWTEST_F(SyncTest, conditionTestWaitfor, TestSize.Level1)
493484543d1Sopenharmony_ci{
494484543d1Sopenharmony_ci    ffrt::condition_variable cond;
495484543d1Sopenharmony_ci    std::atomic_int a = 0;
496484543d1Sopenharmony_ci    ffrt::mutex lock_;
497484543d1Sopenharmony_ci
498484543d1Sopenharmony_ci    ffrt::submit(
499484543d1Sopenharmony_ci        [&]() {
500484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
501484543d1Sopenharmony_ci            cond.wait_for(lck, 100ms, [&] { return a == 1; });
502484543d1Sopenharmony_ci            EXPECT_EQ(a, 2);
503484543d1Sopenharmony_ci        },
504484543d1Sopenharmony_ci        {}, {});
505484543d1Sopenharmony_ci    ffrt::submit(
506484543d1Sopenharmony_ci        [&]() {
507484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
508484543d1Sopenharmony_ci            cond.wait_for(lck, 150ms, [&] { return a == 2; });
509484543d1Sopenharmony_ci            EXPECT_EQ(a, 2);
510484543d1Sopenharmony_ci        },
511484543d1Sopenharmony_ci        {}, {});
512484543d1Sopenharmony_ci    ffrt::submit(
513484543d1Sopenharmony_ci        [&]() {
514484543d1Sopenharmony_ci            std::unique_lock lck(lock_);
515484543d1Sopenharmony_ci            a = 2;
516484543d1Sopenharmony_ci            cond.notify_all();
517484543d1Sopenharmony_ci        },
518484543d1Sopenharmony_ci        {}, {});
519484543d1Sopenharmony_ci    ffrt::wait();
520484543d1Sopenharmony_ci}
521484543d1Sopenharmony_ci
522484543d1Sopenharmony_ciHWTEST_F(SyncTest, conditionTestDataRace, TestSize.Level1)
523484543d1Sopenharmony_ci{
524484543d1Sopenharmony_ci    std::atomic_bool exit {false};
525484543d1Sopenharmony_ci    ffrt::mutex mtx;
526484543d1Sopenharmony_ci    ffrt::condition_variable cv;
527484543d1Sopenharmony_ci    std::atomic_bool start {false};
528484543d1Sopenharmony_ci
529484543d1Sopenharmony_ci    ffrt::thread th {[&] {
530484543d1Sopenharmony_ci        while (!exit) {
531484543d1Sopenharmony_ci            if (start) {
532484543d1Sopenharmony_ci                cv.notify_one();
533484543d1Sopenharmony_ci                ffrt::this_task::sleep_for(1us);
534484543d1Sopenharmony_ci            }
535484543d1Sopenharmony_ci        }
536484543d1Sopenharmony_ci    }};
537484543d1Sopenharmony_ci
538484543d1Sopenharmony_ci    start = true;
539484543d1Sopenharmony_ci    for (int i = 0; i < 2000; ++i) {
540484543d1Sopenharmony_ci        std::unique_lock lk(mtx);
541484543d1Sopenharmony_ci        cv.wait_for(lk, 1us);
542484543d1Sopenharmony_ci    }
543484543d1Sopenharmony_ci    exit = true;
544484543d1Sopenharmony_ci    th.join();
545484543d1Sopenharmony_ci    exit = false;
546484543d1Sopenharmony_ci    start = true;
547484543d1Sopenharmony_ci    ffrt::thread th1 {[&] {
548484543d1Sopenharmony_ci        for (int i = 0; i < 2000; ++i) {
549484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
550484543d1Sopenharmony_ci            cv.wait_for(lk, 1us);
551484543d1Sopenharmony_ci        }
552484543d1Sopenharmony_ci        exit = true;
553484543d1Sopenharmony_ci    }};
554484543d1Sopenharmony_ci
555484543d1Sopenharmony_ci    while (!exit) {
556484543d1Sopenharmony_ci        if (start) {
557484543d1Sopenharmony_ci            cv.notify_one();
558484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(1us);
559484543d1Sopenharmony_ci        }
560484543d1Sopenharmony_ci    }
561484543d1Sopenharmony_ci
562484543d1Sopenharmony_ci    th1.join();
563484543d1Sopenharmony_ci}
564484543d1Sopenharmony_ci
565484543d1Sopenharmony_cistatic void NotifyOneTest(ffrt::mutex& mtx, ffrt::condition_variable& cv)
566484543d1Sopenharmony_ci{
567484543d1Sopenharmony_ci    FFRT_LOGE("[RUN ] notifyone");
568484543d1Sopenharmony_ci    int value = 0;
569484543d1Sopenharmony_ci    bool flag {false};
570484543d1Sopenharmony_ci    ffrt::submit(
571484543d1Sopenharmony_ci        [&]() {
572484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
573484543d1Sopenharmony_ci            cv.wait(lk, [&] { return flag; });
574484543d1Sopenharmony_ci            EXPECT_TRUE(lk.owns_lock());
575484543d1Sopenharmony_ci            value = 123;
576484543d1Sopenharmony_ci        },
577484543d1Sopenharmony_ci        {}, {});
578484543d1Sopenharmony_ci
579484543d1Sopenharmony_ci    EXPECT_EQ(value, 0);
580484543d1Sopenharmony_ci
581484543d1Sopenharmony_ci    ffrt::submit(
582484543d1Sopenharmony_ci        [&]() {
583484543d1Sopenharmony_ci            {
584484543d1Sopenharmony_ci                std::unique_lock lk(mtx);
585484543d1Sopenharmony_ci                flag = true;
586484543d1Sopenharmony_ci            }
587484543d1Sopenharmony_ci            cv.notify_one();
588484543d1Sopenharmony_ci        },
589484543d1Sopenharmony_ci        {}, {});
590484543d1Sopenharmony_ci
591484543d1Sopenharmony_ci    ffrt::wait();
592484543d1Sopenharmony_ci
593484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
594484543d1Sopenharmony_ci}
595484543d1Sopenharmony_ci
596484543d1Sopenharmony_cistatic void WaitUntilTimeoutTest(ffrt::mutex& mtx, ffrt::condition_variable& cv)
597484543d1Sopenharmony_ci{
598484543d1Sopenharmony_ci    constexpr auto eps = 3ms;
599484543d1Sopenharmony_ci
600484543d1Sopenharmony_ci    FFRT_LOGE("[RUN ] WaitUntil timeout&notifyone");
601484543d1Sopenharmony_ci    int value = 0;
602484543d1Sopenharmony_ci    ffrt::submit(
603484543d1Sopenharmony_ci        [&]() {
604484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
605484543d1Sopenharmony_ci            EXPECT_EQ(static_cast<int>(cv.wait_until(lk, std::chrono::steady_clock::now() + 30ms)),
606484543d1Sopenharmony_ci                static_cast<int>(ffrt::cv_status::timeout));
607484543d1Sopenharmony_ci            EXPECT_TRUE(lk.owns_lock());
608484543d1Sopenharmony_ci            value = 123;
609484543d1Sopenharmony_ci        },
610484543d1Sopenharmony_ci        {}, {});
611484543d1Sopenharmony_ci
612484543d1Sopenharmony_ci    EXPECT_EQ(value, 0);
613484543d1Sopenharmony_ci
614484543d1Sopenharmony_ci    ffrt::submit(
615484543d1Sopenharmony_ci        [&]() {
616484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(30ms + eps);
617484543d1Sopenharmony_ci            cv.notify_one();
618484543d1Sopenharmony_ci        },
619484543d1Sopenharmony_ci        {}, {});
620484543d1Sopenharmony_ci
621484543d1Sopenharmony_ci    ffrt::wait();
622484543d1Sopenharmony_ci
623484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
624484543d1Sopenharmony_ci}
625484543d1Sopenharmony_ci
626484543d1Sopenharmony_cistatic void WaitUtilFlagTest_1(ffrt::mutex& mtx, ffrt::condition_variable& cv)
627484543d1Sopenharmony_ci{
628484543d1Sopenharmony_ci    constexpr auto eps = 3ms;
629484543d1Sopenharmony_ci
630484543d1Sopenharmony_ci    FFRT_LOGE("[RUN ] WaitUntil flag&notifyone");
631484543d1Sopenharmony_ci    int value = 0;
632484543d1Sopenharmony_ci    bool flag {false};
633484543d1Sopenharmony_ci
634484543d1Sopenharmony_ci    ffrt::submit(
635484543d1Sopenharmony_ci        [&]() {
636484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
637484543d1Sopenharmony_ci            EXPECT_TRUE(!cv.wait_until(lk, std::chrono::steady_clock::now() + 30ms, [&] { return flag; }));
638484543d1Sopenharmony_ci            value = 123;
639484543d1Sopenharmony_ci        },
640484543d1Sopenharmony_ci        {}, {});
641484543d1Sopenharmony_ci
642484543d1Sopenharmony_ci    EXPECT_EQ(value, 0);
643484543d1Sopenharmony_ci
644484543d1Sopenharmony_ci    ffrt::submit(
645484543d1Sopenharmony_ci        [&]() {
646484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(30ms + eps);
647484543d1Sopenharmony_ci            cv.notify_one();
648484543d1Sopenharmony_ci        },
649484543d1Sopenharmony_ci        {}, {});
650484543d1Sopenharmony_ci
651484543d1Sopenharmony_ci    ffrt::wait();
652484543d1Sopenharmony_ci
653484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
654484543d1Sopenharmony_ci}
655484543d1Sopenharmony_ci
656484543d1Sopenharmony_cistatic void WaitUtilFlagTest_2(ffrt::mutex& mtx, ffrt::condition_variable& cv)
657484543d1Sopenharmony_ci{
658484543d1Sopenharmony_ci    int value = 0;
659484543d1Sopenharmony_ci    bool flag {false};
660484543d1Sopenharmony_ci
661484543d1Sopenharmony_ci    ffrt::submit(
662484543d1Sopenharmony_ci        [&]() {
663484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
664484543d1Sopenharmony_ci            EXPECT_TRUE(cv.wait_until(lk, std::chrono::steady_clock::now() + 30ms, [&] { return flag; }));
665484543d1Sopenharmony_ci            value = 123;
666484543d1Sopenharmony_ci        },
667484543d1Sopenharmony_ci        {}, {});
668484543d1Sopenharmony_ci
669484543d1Sopenharmony_ci    EXPECT_EQ(value, 0);
670484543d1Sopenharmony_ci
671484543d1Sopenharmony_ci    ffrt::submit(
672484543d1Sopenharmony_ci        [&]() {
673484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
674484543d1Sopenharmony_ci            flag = true;
675484543d1Sopenharmony_ci            cv.notify_one();
676484543d1Sopenharmony_ci        },
677484543d1Sopenharmony_ci        {}, {});
678484543d1Sopenharmony_ci
679484543d1Sopenharmony_ci    ffrt::wait();
680484543d1Sopenharmony_ci
681484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
682484543d1Sopenharmony_ci}
683484543d1Sopenharmony_ci
684484543d1Sopenharmony_cistatic void WaitForTest_1(ffrt::mutex& mtx, ffrt::condition_variable& cv)
685484543d1Sopenharmony_ci{
686484543d1Sopenharmony_ci    constexpr auto eps = 3ms;
687484543d1Sopenharmony_ci
688484543d1Sopenharmony_ci    int value = 0;
689484543d1Sopenharmony_ci    ffrt::submit(
690484543d1Sopenharmony_ci        [&]() {
691484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
692484543d1Sopenharmony_ci            EXPECT_EQ(static_cast<int>(cv.wait_for(lk, 30ms)), static_cast<int>(ffrt::cv_status::timeout));
693484543d1Sopenharmony_ci            EXPECT_TRUE(lk.owns_lock());
694484543d1Sopenharmony_ci            value = 123;
695484543d1Sopenharmony_ci        },
696484543d1Sopenharmony_ci        {}, {});
697484543d1Sopenharmony_ci
698484543d1Sopenharmony_ci    EXPECT_EQ(value, 0);
699484543d1Sopenharmony_ci
700484543d1Sopenharmony_ci    ffrt::submit(
701484543d1Sopenharmony_ci        [&]() {
702484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(30ms + eps);
703484543d1Sopenharmony_ci            cv.notify_one();
704484543d1Sopenharmony_ci        },
705484543d1Sopenharmony_ci        {}, {});
706484543d1Sopenharmony_ci
707484543d1Sopenharmony_ci    ffrt::wait();
708484543d1Sopenharmony_ci
709484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
710484543d1Sopenharmony_ci}
711484543d1Sopenharmony_ci
712484543d1Sopenharmony_cistatic void WaitForTest_2(ffrt::mutex& mtx, ffrt::condition_variable& cv)
713484543d1Sopenharmony_ci{
714484543d1Sopenharmony_ci    int value = 0;
715484543d1Sopenharmony_ci    ffrt::submit(
716484543d1Sopenharmony_ci        [&]() {
717484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
718484543d1Sopenharmony_ci            ffrt::submit(
719484543d1Sopenharmony_ci                [&]() {
720484543d1Sopenharmony_ci                    std::unique_lock lk(mtx);
721484543d1Sopenharmony_ci                    cv.notify_one();
722484543d1Sopenharmony_ci                },
723484543d1Sopenharmony_ci                {}, {});
724484543d1Sopenharmony_ci            EXPECT_EQ(static_cast<int>(cv.wait_for(lk, 30ms)), static_cast<int>(ffrt::cv_status::no_timeout));
725484543d1Sopenharmony_ci            EXPECT_EQ(value, 0);
726484543d1Sopenharmony_ci            EXPECT_TRUE(lk.owns_lock());
727484543d1Sopenharmony_ci            value = 123;
728484543d1Sopenharmony_ci        },
729484543d1Sopenharmony_ci        {}, {});
730484543d1Sopenharmony_ci
731484543d1Sopenharmony_ci    ffrt::wait();
732484543d1Sopenharmony_ci
733484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
734484543d1Sopenharmony_ci}
735484543d1Sopenharmony_ci
736484543d1Sopenharmony_cistatic void WaitForTest_3(ffrt::mutex& mtx, ffrt::condition_variable& cv)
737484543d1Sopenharmony_ci{
738484543d1Sopenharmony_ci    constexpr auto eps = 3ms;
739484543d1Sopenharmony_ci
740484543d1Sopenharmony_ci    int value = 0;
741484543d1Sopenharmony_ci    bool flag {false};
742484543d1Sopenharmony_ci
743484543d1Sopenharmony_ci    ffrt::submit(
744484543d1Sopenharmony_ci        [&]() {
745484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
746484543d1Sopenharmony_ci            EXPECT_TRUE(!cv.wait_for(lk, 30ms, [&] { return flag; }));
747484543d1Sopenharmony_ci            value = 123;
748484543d1Sopenharmony_ci        },
749484543d1Sopenharmony_ci        {}, {});
750484543d1Sopenharmony_ci
751484543d1Sopenharmony_ci    EXPECT_EQ(value, 0);
752484543d1Sopenharmony_ci
753484543d1Sopenharmony_ci    ffrt::submit(
754484543d1Sopenharmony_ci        [&]() {
755484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(30ms + eps);
756484543d1Sopenharmony_ci            cv.notify_one();
757484543d1Sopenharmony_ci        },
758484543d1Sopenharmony_ci        {}, {});
759484543d1Sopenharmony_ci
760484543d1Sopenharmony_ci    ffrt::wait();
761484543d1Sopenharmony_ci
762484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
763484543d1Sopenharmony_ci}
764484543d1Sopenharmony_ci
765484543d1Sopenharmony_cistatic void WaitForTest_4(ffrt::mutex& mtx, ffrt::condition_variable& cv)
766484543d1Sopenharmony_ci{
767484543d1Sopenharmony_ci    int value = 0;
768484543d1Sopenharmony_ci    bool flag {false};
769484543d1Sopenharmony_ci
770484543d1Sopenharmony_ci    ffrt::submit(
771484543d1Sopenharmony_ci        [&]() {
772484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
773484543d1Sopenharmony_ci            EXPECT_TRUE(cv.wait_for(lk, 30ms, [&] { return flag; }));
774484543d1Sopenharmony_ci            value = 123;
775484543d1Sopenharmony_ci        },
776484543d1Sopenharmony_ci        {}, {});
777484543d1Sopenharmony_ci
778484543d1Sopenharmony_ci    EXPECT_EQ(value, 0);
779484543d1Sopenharmony_ci
780484543d1Sopenharmony_ci    ffrt::submit(
781484543d1Sopenharmony_ci        [&]() {
782484543d1Sopenharmony_ci            std::unique_lock lk(mtx);
783484543d1Sopenharmony_ci            flag = true;
784484543d1Sopenharmony_ci            cv.notify_one();
785484543d1Sopenharmony_ci        },
786484543d1Sopenharmony_ci        {}, {});
787484543d1Sopenharmony_ci
788484543d1Sopenharmony_ci    ffrt::wait();
789484543d1Sopenharmony_ci
790484543d1Sopenharmony_ci    EXPECT_EQ(value, 123);
791484543d1Sopenharmony_ci}
792484543d1Sopenharmony_ci
793484543d1Sopenharmony_ciHWTEST_F(SyncTest, conditionTest, TestSize.Level1)
794484543d1Sopenharmony_ci{
795484543d1Sopenharmony_ci    ffrt::mutex mtx;
796484543d1Sopenharmony_ci    ffrt::condition_variable cv;
797484543d1Sopenharmony_ci
798484543d1Sopenharmony_ci    NotifyOneTest(mtx, cv);
799484543d1Sopenharmony_ci    WaitUntilTimeoutTest(mtx, cv);
800484543d1Sopenharmony_ci    WaitUtilFlagTest_1(mtx, cv);
801484543d1Sopenharmony_ci    WaitUtilFlagTest_2(mtx, cv);
802484543d1Sopenharmony_ci    WaitForTest_1(mtx, cv);
803484543d1Sopenharmony_ci    WaitForTest_2(mtx, cv);
804484543d1Sopenharmony_ci    WaitForTest_3(mtx, cv);
805484543d1Sopenharmony_ci    WaitForTest_4(mtx, cv);
806484543d1Sopenharmony_ci}
807484543d1Sopenharmony_ci
808484543d1Sopenharmony_cistatic void LockTest(ffrt::shared_mutex& smtx)
809484543d1Sopenharmony_ci{
810484543d1Sopenharmony_ci    int x = 0;
811484543d1Sopenharmony_ci    const int N = 100;
812484543d1Sopenharmony_ci    const int R = 200;
813484543d1Sopenharmony_ci
814484543d1Sopenharmony_ci    ffrt::submit(
815484543d1Sopenharmony_ci        [&]() {
816484543d1Sopenharmony_ci            for (int i = 0; i < N; i++) {
817484543d1Sopenharmony_ci                smtx.lock();
818484543d1Sopenharmony_ci                x++;
819484543d1Sopenharmony_ci                smtx.unlock();
820484543d1Sopenharmony_ci            }
821484543d1Sopenharmony_ci        },
822484543d1Sopenharmony_ci        {}, {});
823484543d1Sopenharmony_ci
824484543d1Sopenharmony_ci    for (int j = 0; j < N; ++j) {
825484543d1Sopenharmony_ci        smtx.lock();
826484543d1Sopenharmony_ci        x++;
827484543d1Sopenharmony_ci        smtx.unlock();
828484543d1Sopenharmony_ci    }
829484543d1Sopenharmony_ci
830484543d1Sopenharmony_ci    ffrt::wait();
831484543d1Sopenharmony_ci    EXPECT_EQ(x, R);
832484543d1Sopenharmony_ci}
833484543d1Sopenharmony_ci
834484543d1Sopenharmony_cistatic void TryLockTest(ffrt::shared_mutex& smtx)
835484543d1Sopenharmony_ci{
836484543d1Sopenharmony_ci    int x = 0;
837484543d1Sopenharmony_ci    const int N = 100;
838484543d1Sopenharmony_ci    ffrt::submit(
839484543d1Sopenharmony_ci        [&]() {
840484543d1Sopenharmony_ci            smtx.lock();
841484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(20ms);
842484543d1Sopenharmony_ci            smtx.unlock();
843484543d1Sopenharmony_ci        },
844484543d1Sopenharmony_ci        {}, {});
845484543d1Sopenharmony_ci
846484543d1Sopenharmony_ci    ffrt::this_task::sleep_for(2ms);
847484543d1Sopenharmony_ci
848484543d1Sopenharmony_ci    bool ret = smtx.try_lock();
849484543d1Sopenharmony_ci    EXPECT_EQ(ret, false);
850484543d1Sopenharmony_ci    if (ret) {
851484543d1Sopenharmony_ci        smtx.unlock();
852484543d1Sopenharmony_ci    }
853484543d1Sopenharmony_ci    ffrt::wait();
854484543d1Sopenharmony_ci
855484543d1Sopenharmony_ci    ret = smtx.try_lock();
856484543d1Sopenharmony_ci    EXPECT_EQ(ret, true);
857484543d1Sopenharmony_ci    if (ret) {
858484543d1Sopenharmony_ci        smtx.unlock();
859484543d1Sopenharmony_ci    }
860484543d1Sopenharmony_ci}
861484543d1Sopenharmony_ci
862484543d1Sopenharmony_cistatic void LockSharedTest(ffrt::shared_mutex& smtx)
863484543d1Sopenharmony_ci{
864484543d1Sopenharmony_ci    int x = 0;
865484543d1Sopenharmony_ci    const int N = 100;
866484543d1Sopenharmony_ci
867484543d1Sopenharmony_ci    ffrt::submit(
868484543d1Sopenharmony_ci        [&]() {
869484543d1Sopenharmony_ci            smtx.lock_shared();
870484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(20ms);
871484543d1Sopenharmony_ci            x = N;
872484543d1Sopenharmony_ci            smtx.unlock_shared();
873484543d1Sopenharmony_ci        },
874484543d1Sopenharmony_ci        {}, {});
875484543d1Sopenharmony_ci    ffrt::this_task::sleep_for(2ms);
876484543d1Sopenharmony_ci
877484543d1Sopenharmony_ci    smtx.lock_shared();
878484543d1Sopenharmony_ci    EXPECT_EQ(x, 0);
879484543d1Sopenharmony_ci    smtx.unlock_shared();
880484543d1Sopenharmony_ci
881484543d1Sopenharmony_ci    smtx.lock();
882484543d1Sopenharmony_ci    EXPECT_EQ(x, N);
883484543d1Sopenharmony_ci    smtx.unlock();
884484543d1Sopenharmony_ci
885484543d1Sopenharmony_ci    ffrt::wait();
886484543d1Sopenharmony_ci
887484543d1Sopenharmony_ci    smtx.lock_shared();
888484543d1Sopenharmony_ci    EXPECT_EQ(x, N);
889484543d1Sopenharmony_ci    smtx.unlock_shared();
890484543d1Sopenharmony_ci}
891484543d1Sopenharmony_ci
892484543d1Sopenharmony_cistatic void TryLockSharedTest(ffrt::shared_mutex& smtx)
893484543d1Sopenharmony_ci{
894484543d1Sopenharmony_ci    int x = 0;
895484543d1Sopenharmony_ci    const int N = 100;
896484543d1Sopenharmony_ci
897484543d1Sopenharmony_ci    ffrt::submit(
898484543d1Sopenharmony_ci        [&]() {
899484543d1Sopenharmony_ci            smtx.lock_shared();
900484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(20ms);
901484543d1Sopenharmony_ci            x = N;
902484543d1Sopenharmony_ci            smtx.unlock_shared();
903484543d1Sopenharmony_ci        },
904484543d1Sopenharmony_ci        {}, {});
905484543d1Sopenharmony_ci    ffrt::this_task::sleep_for(2ms);
906484543d1Sopenharmony_ci
907484543d1Sopenharmony_ci    bool ret = smtx.try_lock_shared();
908484543d1Sopenharmony_ci    EXPECT_EQ(ret, true);
909484543d1Sopenharmony_ci    EXPECT_EQ(x, 0);
910484543d1Sopenharmony_ci    if (ret) {
911484543d1Sopenharmony_ci        smtx.unlock_shared();
912484543d1Sopenharmony_ci    }
913484543d1Sopenharmony_ci    ffrt::wait();
914484543d1Sopenharmony_ci
915484543d1Sopenharmony_ci    ret = smtx.try_lock_shared();
916484543d1Sopenharmony_ci    EXPECT_EQ(ret, true);
917484543d1Sopenharmony_ci    EXPECT_EQ(x, N);
918484543d1Sopenharmony_ci    if (ret) {
919484543d1Sopenharmony_ci        smtx.unlock_shared();
920484543d1Sopenharmony_ci    }
921484543d1Sopenharmony_ci
922484543d1Sopenharmony_ci    ffrt::submit(
923484543d1Sopenharmony_ci        [&]() {
924484543d1Sopenharmony_ci            smtx.lock();
925484543d1Sopenharmony_ci            ffrt::this_task::sleep_for(20ms);
926484543d1Sopenharmony_ci            x = 0;
927484543d1Sopenharmony_ci            smtx.unlock();
928484543d1Sopenharmony_ci        },
929484543d1Sopenharmony_ci        {}, {});
930484543d1Sopenharmony_ci    ffrt::this_task::sleep_for(2ms);
931484543d1Sopenharmony_ci
932484543d1Sopenharmony_ci    ret = smtx.try_lock_shared();
933484543d1Sopenharmony_ci    EXPECT_EQ(ret, false);
934484543d1Sopenharmony_ci    EXPECT_EQ(x, N);
935484543d1Sopenharmony_ci    if (ret) {
936484543d1Sopenharmony_ci        smtx.unlock_shared();
937484543d1Sopenharmony_ci    }
938484543d1Sopenharmony_ci    ffrt::wait();
939484543d1Sopenharmony_ci
940484543d1Sopenharmony_ci    ret = smtx.try_lock_shared();
941484543d1Sopenharmony_ci    EXPECT_EQ(ret, true);
942484543d1Sopenharmony_ci    EXPECT_EQ(x, 0);
943484543d1Sopenharmony_ci    if (ret) {
944484543d1Sopenharmony_ci        smtx.unlock_shared();
945484543d1Sopenharmony_ci    }
946484543d1Sopenharmony_ci}
947484543d1Sopenharmony_ci
948484543d1Sopenharmony_ciHWTEST_F(SyncTest, sharedMutexTest, TestSize.Level1)
949484543d1Sopenharmony_ci{
950484543d1Sopenharmony_ci    ffrt::shared_mutex smtx;
951484543d1Sopenharmony_ci    LockTest(smtx);
952484543d1Sopenharmony_ci    TryLockTest(smtx);
953484543d1Sopenharmony_ci    LockSharedTest(smtx);
954484543d1Sopenharmony_ci    TryLockSharedTest(smtx);
955484543d1Sopenharmony_ci}
956484543d1Sopenharmony_ci
957484543d1Sopenharmony_ciHWTEST_F(SyncTest, thread1, TestSize.Level1)
958484543d1Sopenharmony_ci{
959484543d1Sopenharmony_ci    auto ThreadFunc1 = [](int a, const int& b) {
960484543d1Sopenharmony_ci        FFRT_LOGW("a = %d, b = %d", a, b);
961484543d1Sopenharmony_ci        return 0;
962484543d1Sopenharmony_ci    };
963484543d1Sopenharmony_ci
964484543d1Sopenharmony_ci    auto ThreadFunc2 = [](const char* a, const char* b) {
965484543d1Sopenharmony_ci        FFRT_LOGW("%s %s", a, b);
966484543d1Sopenharmony_ci        return 0;
967484543d1Sopenharmony_ci    };
968484543d1Sopenharmony_ci
969484543d1Sopenharmony_ci    {
970484543d1Sopenharmony_ci        int value = 0;
971484543d1Sopenharmony_ci        std::thread th0 {[&value, &ThreadFunc1, &ThreadFunc2] {
972484543d1Sopenharmony_ci            std::thread th1 {ThreadFunc1, 10, 20};
973484543d1Sopenharmony_ci            std::thread th2 {ThreadFunc2, "hello", "ffrt"};
974484543d1Sopenharmony_ci            th1.join();
975484543d1Sopenharmony_ci            th2.join();
976484543d1Sopenharmony_ci
977484543d1Sopenharmony_ci            value = 123;
978484543d1Sopenharmony_ci            FFRT_LOGW("value = %d", value);
979484543d1Sopenharmony_ci        }};
980484543d1Sopenharmony_ci        th0.join();
981484543d1Sopenharmony_ci        assert(!th0.joinable());
982484543d1Sopenharmony_ci        EXPECT_EQ(value, 123);
983484543d1Sopenharmony_ci    }
984484543d1Sopenharmony_ci    {
985484543d1Sopenharmony_ci        int value = 0;
986484543d1Sopenharmony_ci        ffrt::thread th0 {[&value, &ThreadFunc1, &ThreadFunc2] {
987484543d1Sopenharmony_ci            ffrt::thread th1 {ThreadFunc1, 10, 20};
988484543d1Sopenharmony_ci            ffrt::thread th2 {ThreadFunc2, "hello", "ffrt"};
989484543d1Sopenharmony_ci            th1.join();
990484543d1Sopenharmony_ci            th2.join();
991484543d1Sopenharmony_ci
992484543d1Sopenharmony_ci            value = 123;
993484543d1Sopenharmony_ci            FFRT_LOGW("value = %d", value);
994484543d1Sopenharmony_ci        }};
995484543d1Sopenharmony_ci        th0.join();
996484543d1Sopenharmony_ci        assert(!th0.joinable());
997484543d1Sopenharmony_ci        EXPECT_EQ(value, 123);
998484543d1Sopenharmony_ci    }
999484543d1Sopenharmony_ci}
1000484543d1Sopenharmony_ci
1001484543d1Sopenharmony_civoid f1(int n)
1002484543d1Sopenharmony_ci{
1003484543d1Sopenharmony_ci    for (int i = 0; i < 5; ++i) {
1004484543d1Sopenharmony_ci        std::cout << "Thread 1 executing\n";
1005484543d1Sopenharmony_ci        ++n;
1006484543d1Sopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(10));
1007484543d1Sopenharmony_ci    }
1008484543d1Sopenharmony_ci}
1009484543d1Sopenharmony_ci
1010484543d1Sopenharmony_civoid f2(int& n)
1011484543d1Sopenharmony_ci{
1012484543d1Sopenharmony_ci    for (int i = 0; i < 5; ++i) {
1013484543d1Sopenharmony_ci        std::cout << "Thread 2 executing\n";
1014484543d1Sopenharmony_ci        ++n;
1015484543d1Sopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(10));
1016484543d1Sopenharmony_ci    }
1017484543d1Sopenharmony_ci}
1018484543d1Sopenharmony_ci
1019484543d1Sopenharmony_ciclass foo {
1020484543d1Sopenharmony_cipublic:
1021484543d1Sopenharmony_ci    void bar()
1022484543d1Sopenharmony_ci    {
1023484543d1Sopenharmony_ci        for (int i = 0; i < 5; ++i) {
1024484543d1Sopenharmony_ci            std::cout << "Thread 3 executing\n";
1025484543d1Sopenharmony_ci            ++n;
1026484543d1Sopenharmony_ci            std::this_thread::sleep_for(std::chrono::milliseconds(10));
1027484543d1Sopenharmony_ci        }
1028484543d1Sopenharmony_ci    }
1029484543d1Sopenharmony_ci    int n = 0;
1030484543d1Sopenharmony_ci};
1031484543d1Sopenharmony_ci
1032484543d1Sopenharmony_ciclass baz {
1033484543d1Sopenharmony_cipublic:
1034484543d1Sopenharmony_ci    void operator()()
1035484543d1Sopenharmony_ci    {
1036484543d1Sopenharmony_ci        for (int i = 0; i < 5; ++i) {
1037484543d1Sopenharmony_ci            std::cout << "Thread 4 executing\n";
1038484543d1Sopenharmony_ci            ++n;
1039484543d1Sopenharmony_ci            std::this_thread::sleep_for(std::chrono::milliseconds(10));
1040484543d1Sopenharmony_ci        }
1041484543d1Sopenharmony_ci    }
1042484543d1Sopenharmony_ci    int n = 0;
1043484543d1Sopenharmony_ci};
1044484543d1Sopenharmony_ci
1045484543d1Sopenharmony_ciHWTEST_F(SyncTest, thread2, TestSize.Level1)
1046484543d1Sopenharmony_ci{
1047484543d1Sopenharmony_ci    {
1048484543d1Sopenharmony_ci        int n = 0;
1049484543d1Sopenharmony_ci        foo f;
1050484543d1Sopenharmony_ci        baz b;
1051484543d1Sopenharmony_ci        {
1052484543d1Sopenharmony_ci            std::thread t2(f1, n + 1);
1053484543d1Sopenharmony_ci            t2.detach(); // test detach
1054484543d1Sopenharmony_ci        }
1055484543d1Sopenharmony_ci        std::thread t1; // t1 is not a thread
1056484543d1Sopenharmony_ci        std::thread t2(f1, n + 1); // pass by value
1057484543d1Sopenharmony_ci        std::thread t3(f2, std::ref(n)); // pass by reference
1058484543d1Sopenharmony_ci        std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
1059484543d1Sopenharmony_ci        std::thread t5(&foo::bar, &f); // t5 runs foo::bar() on object f
1060484543d1Sopenharmony_ci        std::thread t6(b); // t6 runs baz::operator() on a copy of object b
1061484543d1Sopenharmony_ci        EXPECT_EQ(t1.joinable(), false);
1062484543d1Sopenharmony_ci        EXPECT_EQ(t2.joinable(), true);
1063484543d1Sopenharmony_ci        t2.join();
1064484543d1Sopenharmony_ci        EXPECT_EQ(t2.joinable(), false);
1065484543d1Sopenharmony_ci        t4.join();
1066484543d1Sopenharmony_ci        t5.join();
1067484543d1Sopenharmony_ci        t6.join();
1068484543d1Sopenharmony_ci        EXPECT_EQ(n, 5);
1069484543d1Sopenharmony_ci        EXPECT_EQ(f.n, 5);
1070484543d1Sopenharmony_ci        EXPECT_EQ(b.n, 0);
1071484543d1Sopenharmony_ci    }
1072484543d1Sopenharmony_ci    FFRT_LOGW("ffrt version");
1073484543d1Sopenharmony_ci    {
1074484543d1Sopenharmony_ci        int n = 0;
1075484543d1Sopenharmony_ci        foo f;
1076484543d1Sopenharmony_ci        baz b;
1077484543d1Sopenharmony_ci        {
1078484543d1Sopenharmony_ci            ffrt::thread t2(f1, n + 1);
1079484543d1Sopenharmony_ci            t2.detach(); // test detach
1080484543d1Sopenharmony_ci        }
1081484543d1Sopenharmony_ci        ffrt::thread t1; // t1 is not a thread
1082484543d1Sopenharmony_ci        ffrt::thread t2(f1, n + 1); // pass by value
1083484543d1Sopenharmony_ci        ffrt::thread t3(f2, std::ref(n)); // pass by reference
1084484543d1Sopenharmony_ci        ffrt::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
1085484543d1Sopenharmony_ci        ffrt::thread t5(&foo::bar, &f); // t5 runs foo::bar() on object f
1086484543d1Sopenharmony_ci        ffrt::thread t6(b); // t6 runs baz::operator() on a copy of object b
1087484543d1Sopenharmony_ci        EXPECT_EQ(t1.joinable(), false);
1088484543d1Sopenharmony_ci        EXPECT_EQ(t2.joinable(), true);
1089484543d1Sopenharmony_ci        t2.join();
1090484543d1Sopenharmony_ci        EXPECT_EQ(t2.joinable(), false);
1091484543d1Sopenharmony_ci        EXPECT_EQ(t3.joinable(), false);
1092484543d1Sopenharmony_ci        EXPECT_EQ(t4.joinable(), true);
1093484543d1Sopenharmony_ci        t4.join();
1094484543d1Sopenharmony_ci        EXPECT_EQ(t4.joinable(), false);
1095484543d1Sopenharmony_ci        t5.join();
1096484543d1Sopenharmony_ci        t6.join();
1097484543d1Sopenharmony_ci        EXPECT_EQ(n, 5);
1098484543d1Sopenharmony_ci        EXPECT_EQ(f.n, 5);
1099484543d1Sopenharmony_ci        EXPECT_EQ(b.n, 0);
1100484543d1Sopenharmony_ci    }
1101484543d1Sopenharmony_ci}
1102484543d1Sopenharmony_ci
1103484543d1Sopenharmony_ciHWTEST_F(SyncTest, thread_with_qos, TestSize.Level1)
1104484543d1Sopenharmony_ci{
1105484543d1Sopenharmony_ci    int a = 0;
1106484543d1Sopenharmony_ci    auto task = [&] {
1107484543d1Sopenharmony_ci        a++;
1108484543d1Sopenharmony_ci    };
1109484543d1Sopenharmony_ci    ffrt::thread(static_cast<int>(ffrt::qos_user_initiated), task).join();
1110484543d1Sopenharmony_ci    EXPECT_EQ(1, a);
1111484543d1Sopenharmony_ci}
1112484543d1Sopenharmony_ci
1113484543d1Sopenharmony_ciHWTEST_F(SyncTest, thread_with_name, TestSize.Level1)
1114484543d1Sopenharmony_ci{
1115484543d1Sopenharmony_ci    int a = 0;
1116484543d1Sopenharmony_ci    auto task = [&] {
1117484543d1Sopenharmony_ci        a++;
1118484543d1Sopenharmony_ci    };
1119484543d1Sopenharmony_ci    std::string name = "thread_test";
1120484543d1Sopenharmony_ci    ffrt::thread(name.c_str(), static_cast<int>(ffrt::qos_user_initiated), task).join();
1121484543d1Sopenharmony_ci    EXPECT_EQ(1, a);
1122484543d1Sopenharmony_ci}
1123484543d1Sopenharmony_ci
1124484543d1Sopenharmony_cistruct F {
1125484543d1Sopenharmony_ci    template<typename T, typename U>
1126484543d1Sopenharmony_ci    void operator()(T, U, int& a)
1127484543d1Sopenharmony_ci    {
1128484543d1Sopenharmony_ci        using std::is_same;
1129484543d1Sopenharmony_ci        using std::reference_wrapper;
1130484543d1Sopenharmony_ci        static_assert(is_same<T, reference_wrapper<int>>::value, "");
1131484543d1Sopenharmony_ci        static_assert(is_same<U, reference_wrapper<const int>>::value, "");
1132484543d1Sopenharmony_ci        a++;
1133484543d1Sopenharmony_ci    }
1134484543d1Sopenharmony_ci};
1135484543d1Sopenharmony_ci
1136484543d1Sopenharmony_ciHWTEST_F(SyncTest, thread_with_ref_check, TestSize.Level1)
1137484543d1Sopenharmony_ci{
1138484543d1Sopenharmony_ci    int a = 0;
1139484543d1Sopenharmony_ci    ffrt::thread t(F{}, std::ref(a), std::cref(a), std::ref(a));
1140484543d1Sopenharmony_ci    t.join();
1141484543d1Sopenharmony_ci    EXPECT_EQ(1, a);
1142484543d1Sopenharmony_ci}
1143484543d1Sopenharmony_ci
1144484543d1Sopenharmony_cistruct A {
1145484543d1Sopenharmony_ci    A() = default;
1146484543d1Sopenharmony_ci    explicit A(const A&) = default;
1147484543d1Sopenharmony_ci};
1148484543d1Sopenharmony_ci
1149484543d1Sopenharmony_civoid func(const A&) { }
1150484543d1Sopenharmony_ci
1151484543d1Sopenharmony_ciHWTEST_F(SyncTest, thread_with_ref, TestSize.Level1)
1152484543d1Sopenharmony_ci{
1153484543d1Sopenharmony_ci    ffrt::thread t(func, A{});
1154484543d1Sopenharmony_ci    t.join();
1155484543d1Sopenharmony_ci}
1156484543d1Sopenharmony_ci
1157484543d1Sopenharmony_ciHWTEST_F(SyncTest, future_wait, TestSize.Level1)
1158484543d1Sopenharmony_ci{
1159484543d1Sopenharmony_ci    ffrt::packaged_task<int()> task([] { return 7; });
1160484543d1Sopenharmony_ci    ffrt::future<int> f1 = task.get_future();
1161484543d1Sopenharmony_ci    ffrt::thread t(std::move(task));
1162484543d1Sopenharmony_ci
1163484543d1Sopenharmony_ci    ffrt::future<int> f2 = ffrt::async([] { return 8; });
1164484543d1Sopenharmony_ci
1165484543d1Sopenharmony_ci    ffrt::promise<int> p;
1166484543d1Sopenharmony_ci    ffrt::future<int> f3 = p.get_future();
1167484543d1Sopenharmony_ci    ffrt::thread([&p] { p.set_value(9); }).detach();
1168484543d1Sopenharmony_ci
1169484543d1Sopenharmony_ci    std::cout << "Waiting..." << std::flush;
1170484543d1Sopenharmony_ci    f1.wait();
1171484543d1Sopenharmony_ci    f2.wait();
1172484543d1Sopenharmony_ci    f3.wait();
1173484543d1Sopenharmony_ci    std::cout << "Done!\nResults are: "
1174484543d1Sopenharmony_ci              << f1.get() << ' ' << f2.get() << ' ' << f3.get() << '\n';
1175484543d1Sopenharmony_ci    t.join();
1176484543d1Sopenharmony_ci}
1177