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¬ifyone"); 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¬ifyone"); 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