• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <mutex>
17 #include <future>
18 #include <chrono>
19 #include <random>
20 #include <gtest/gtest.h>
21 #include "sync/sync.h"
22 #include "ffrt_inner.h"
23 #include "dfx/log/ffrt_log_api.h"
24 #include "c/thread.h"
25 #include "c/ffrt_ipc.h"
26 #include "tm/cpu_task.h"
27 #include "../common.h"
28 
29 extern "C" int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
30 extern "C" int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
31 extern "C" int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
32 extern "C" int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
33 extern "C" int ffrt_mutex_init(ffrt_mutex_t *mutex, const ffrt_mutexattr_t* attr);
34 extern "C" int ffrt_mutex_lock(ffrt_mutex_t *mutex);
35 extern "C" int ffrt_mutex_unlock(ffrt_mutex_t *mutex);
36 extern "C" int ffrt_mutex_trylock(ffrt_mutex_t *mutex);
37 extern "C" int ffrt_mutex_destroy(ffrt_mutex_t *mutex);
38 
39 using namespace std;
40 using namespace testing;
41 #ifdef HWTEST_TESTING_EXT_ENABLE
42 using namespace testing::ext;
43 #endif
44 
45 class SyncTest : public testing::Test {
46 protected:
SetUpTestCase()47     static void SetUpTestCase()
48     {
49     }
50 
TearDownTestCase()51     static void TearDownTestCase()
52     {
53     }
54 
SetUp()55     void SetUp() override
56     {
57     }
58 
TearDown()59     void TearDown() override
60     {
61     }
62 };
63 
64 /**
65  * @tc.name: mutexattr_nullptr_fail
66  * @tc.desc: Test function of mutexattr when the input is nullptr;
67  * @tc.type: FUNC
68  */
69 HWTEST_F(SyncTest, mutexattr_nullptr_fail, TestSize.Level1)
70 {
71     int ret = ffrt_mutexattr_init(nullptr);
72     EXPECT_EQ(ret, ffrt_error_inval);
73     ret = ffrt_mutexattr_settype(nullptr, 0);
74     EXPECT_EQ(ret, ffrt_error_inval);
75     ret = ffrt_mutexattr_gettype(nullptr, nullptr);
76     EXPECT_EQ(ret, ffrt_error_inval);
77     ret = ffrt_mutexattr_destroy(nullptr);
78     EXPECT_EQ(ret, ffrt_error_inval);
79 }
80 
81 /**
82  * @tc.name: mutex_nullptr_fail
83  * @tc.desc: Test function of mutex when the input is nullptr;
84  * @tc.type: FUNC
85  */
86 HWTEST_F(SyncTest, mutex_nullptr_fail, TestSize.Level1)
87 {
88     int ret = ffrt_mutex_init(nullptr, nullptr);
89     EXPECT_EQ(ret, ffrt_error_inval);
90     ret = ffrt_mutex_lock(nullptr);
91     EXPECT_EQ(ret, ffrt_error_inval);
92     ret = ffrt_mutex_unlock(nullptr);
93     EXPECT_EQ(ret, ffrt_error_inval);
94     ret = ffrt_mutex_trylock(nullptr);
95     EXPECT_EQ(ret, ffrt_error_inval);
96     ffrt_mutex_destroy(nullptr);
97 }
98 
99 /**
100  * @tc.name: mutex_try_lock
101  * @tc.desc: Test function of mutex:try_lock
102  * @tc.type: FUNC
103  */
104 HWTEST_F(SyncTest, mutex_try_lock, TestSize.Level1)
105 {
106     int val = -1;
107     ffrt::mutex lock;
108     lock.lock();
109     val = lock.try_lock();
110     EXPECT_EQ(val, 0);
111     lock.unlock();
112     val = lock.try_lock();
113     EXPECT_EQ(val, 1);
114     lock.unlock();
115     lock.unlock();
116 }
117 
118 /**
119  * @tc.name: recursive_mutex_try_lock
120  * @tc.desc: Test function of recursive mutex:try_lock
121  * @tc.type: FUNC
122  */
123 HWTEST_F(SyncTest, recursive_mutex_try_lock, TestSize.Level1)
124 {
125     int val = -1;
126     ffrt::recursive_mutex lock;
127     lock.lock();
128     val = lock.try_lock();
129     EXPECT_EQ(val, 1);
130     lock.unlock();
131     val = lock.try_lock();
132     EXPECT_EQ(val, 1);
133     lock.unlock();
134     lock.unlock();
135 }
136 
137 /**
138  * @tc.name: mutex_lock_with_BlockThread
139  * @tc.desc: Test function of mutex:lock in Thread mode
140  * @tc.type: FUNC
141  */
142 HWTEST_F(SyncTest, mutex_lock_with_BlockThread, TestSize.Level1)
143 {
144     int x = 0;
145     ffrt::mutex lock;
__anon2aac0dff0102() 146     ffrt::submit([&]() {
147         ffrt::this_task::sleep_for(10ms);
148         ffrt_this_task_set_legacy_mode(true);
149         lock.lock();
150         ffrt::submit([&]() {
151             EXPECT_EQ(x, 1);
152             }, {&x}, {});
153         ffrt::submit([&]() {
154             x++;
155             EXPECT_EQ(x, 2);
156             }, {&x}, {&x});
157         ffrt::submit([&]() {
158             EXPECT_EQ(x, 2);
159             }, {&x}, {});
160         ffrt::wait();
161         lock.unlock();
162         ffrt_this_task_set_legacy_mode(false);
163         }, {}, {}, ffrt::task_attr().name("t2"));
164 
__anon2aac0dff0d02() 165     ffrt::submit([&]() {
166         ffrt_this_task_set_legacy_mode(true);
167         lock.lock();
168         ffrt::submit([&]() {
169             EXPECT_EQ(x, 0);
170             }, {&x}, {});
171         ffrt::submit([&]() {
172             x++;
173             EXPECT_EQ(x, 1);
174             }, {&x}, {&x});
175         ffrt::submit([&]() {
176             EXPECT_EQ(x, 1);
177             }, {&x}, {});
178         ffrt::wait();
179         lock.unlock();
180         ffrt_this_task_set_legacy_mode(false);
181         }, {}, {}, ffrt::task_attr().name("t1"));
182     ffrt::wait();
183 }
184 
185 /**
186  * @tc.name: set_legacy_mode_within_nested_task
187  * @tc.desc: Test function of mutex:lock in Thread mode
188  * @tc.type: FUNC
189  */
190 HWTEST_F(SyncTest, set_legacy_mode_within_nested_task, TestSize.Level1)
191 {
192     int x = 0;
__anon2aac0dff1902() 193     ffrt::submit([&]() {
194         ffrt_this_task_set_legacy_mode(true);
195         ffrt_this_task_set_legacy_mode(true);
196         ffrt::CPUEUTask* ctx = ffrt::ExecuteCtx::Cur()->task;
197         bool result = ffrt::LegacyMode(ctx);
198         EXPECT_TRUE(result);
199         ffrt::submit([&]() {
200             ffrt_this_task_set_legacy_mode(true);
201             ffrt::CPUEUTask* ctx = ffrt::ExecuteCtx::Cur()->task;
202             bool result = ffrt::LegacyMode(ctx);
203             EXPECT_TRUE(result);
204             x++;
205             EXPECT_EQ(x, 1);
206             ffrt_this_task_set_legacy_mode(false);
207             ffrt_this_task_set_legacy_mode(false);
208             ctx = ffrt::ExecuteCtx::Cur()->task;
209             int legacycount = ctx->legacyCountNum;
210             EXPECT_EQ(legacycount, -1);
211             }, {}, {}, ffrt::task_attr().qos(3));
212         ffrt::wait();
213         ffrt_this_task_set_legacy_mode(false);
214         ffrt_this_task_set_legacy_mode(false);
215         ctx = ffrt::ExecuteCtx::Cur()->task;
216         int legacycount = ctx->legacyCountNum;
217         EXPECT_EQ(legacycount, 0);
218         }, {}, {}, ffrt::task_attr().qos(3));
219     ffrt::wait();
220     EXPECT_EQ(x, 1);
221 }
222 
223 HWTEST_F(SyncTest, class_data_align, TestSize.Level1)
224 {
225     struct memTest {
226         bool isFlag; // Construct an unaligned address
227         ffrt::mutex mtx;
228         ffrt::task_attr taskAttr;
229         ffrt::task_handle taskHandle;
230         ffrt::condition_variable cv;
231         ffrt::thread t;
232     };
233     memTest m;
234     {
235         ffrt::mutex* mtxAddr = &m.mtx;
236         uintptr_t addr_int = reinterpret_cast<uintptr_t>(mtxAddr);
237         EXPECT_EQ((addr_int % 4), 0);
238 
239         ffrt::task_attr* attrAddr = &m.taskAttr;
240         addr_int = reinterpret_cast<uintptr_t>(attrAddr);
241         EXPECT_EQ((addr_int % 4), 0);
242 
243         ffrt::task_handle* handleAddr = &m.taskHandle;
244         addr_int = reinterpret_cast<uintptr_t>(handleAddr);
245         EXPECT_EQ((addr_int % 4), 0);
246 
247         ffrt::condition_variable* cvAddr = &m.cv;
248         addr_int = reinterpret_cast<uintptr_t>(cvAddr);
249         EXPECT_EQ((addr_int % 4), 0);
250 
251         ffrt::thread* tAddr = &m.t;
252         addr_int = reinterpret_cast<uintptr_t>(tAddr);
253         EXPECT_EQ((addr_int % 4), 0);
254     }
255 }
256 
257 HWTEST_F(SyncTest, lock_stress, TestSize.Level1)
258 {
259     // trigger lazy init
__anon2aac0dff1f02() 260     ffrt::submit([&]() {}, {}, {});
261     ffrt::wait();
262 
263     const int N = 10;
264     const int M = 1000;
265     const int J = 10000;
266     ffrt::mutex lock;
267     // std::mutex lock;
268     int acc = 0;
269     for (int i = 0; i < N; ++i) {
270         ffrt::submit(
__anon2aac0dff2202() 271             [&]() {
272                 for (int j = 0; j < M; ++j) {
273                     lock.lock();
274                     acc++;
275                     lock.unlock();
276                 }
277             },
__anon2aac0dff2402() 278             {}, {});
279     }
280 
281     for (int j = 0; j < J; ++j) {
282         lock.lock();
283         acc++;
284         lock.unlock();
285     }
286 
287     ffrt::wait();
288     EXPECT_EQ(acc, (M * N + J));
289 }
290 
291 HWTEST_F(SyncTest, lock_stress_c_api, TestSize.Level1)
292 {
293     // trigger lazy init
__anon2aac0dff2702() 294     ffrt::submit([&]() {}, {}, {});
295     ffrt::wait();
296 
297     const int N = 10;
298     const int M = 1000;
299     const int J = 10000;
300     ffrt::mutex* lock = new ffrt::mutex;
301     int acc = 0;
302     for (int i = 0; i < N; ++i) {
303         ffrt::submit(
__anon2aac0dff2802() 304             [&]() {
305                 for (int j = 0; j < M; ++j) {
306                     lock->lock();
307                     acc++;
308                     lock->unlock();
309                 }
310             },
__anon2aac0dff2a02() 311             {}, {});
312     }
313 
314     for (int j = 0; j < J; ++j) {
315         lock->lock();
316         acc++;
317         lock->unlock();
318     }
319 
320     ffrt::wait();
321     EXPECT_EQ(acc, (M * N + J));
322     delete lock;
323 }
324 
325 /**
326  * @tc.name: recursive_lock_stress
327  * @tc.desc: Test C++ function of recursive mutex:lock in stress mode
328  * @tc.type: FUNC
329  */
330 HWTEST_F(SyncTest, recursive_lock_stress, TestSize.Level1)
331 {
332     // trigger lazy init
__anon2aac0dff2b02() 333     ffrt::submit([&]() {}, {}, {});
334     ffrt::wait();
335 
336     const int N = 10;
337     const int M = 1000;
338     const int J = 10000;
339     ffrt::recursive_mutex lock;
340     // std::mutex lock;
341     int acc = 0;
342     for (int i = 0; i < N; ++i) {
343         ffrt::submit(
__anon2aac0dff2e02() 344             [&]() {
345                 for (int j = 0; j < M; ++j) {
346                     lock.lock();
347                     acc++;
348                     lock.unlock();
349                 }
350             },
__anon2aac0dff3002() 351             {}, {});
352     }
353 
354     for (int j = 0; j < J; ++j) {
355         lock.lock();
356         acc++;
357         lock.unlock();
358     }
359 
360     ffrt::wait();
361     EXPECT_EQ(acc, (M * N + J));
362 }
363 
364 /**
365  * @tc.name: recursive_lock_stress
366  * @tc.desc: Test C function of recursive mutex:lock in stress mode
367  * @tc.type: FUNC
368  */
369 HWTEST_F(SyncTest, recursive_lock_stress_c_api, TestSize.Level1)
370 {
371     // trigger lazy init
__anon2aac0dff3102() 372     ffrt::submit([&]() {}, {}, {});
373     ffrt::wait();
374 
375     const int N = 10;
376     const int M = 1000;
377     const int J = 10000;
378     ffrt::recursive_mutex* lock = new ffrt::recursive_mutex;
379     int acc = 0;
380     for (int i = 0; i < N; ++i) {
381         ffrt::submit(
__anon2aac0dff3402() 382             [&]() {
383                 for (int j = 0; j < M; ++j) {
384                     lock->lock();
385                     acc++;
386                     lock->unlock();
387                 }
388             },
__anon2aac0dff3502() 389             {}, {});
390     }
391 
392     for (int j = 0; j < J; ++j) {
393         lock->lock();
394         acc++;
395         lock->unlock();
396     }
397 
398     ffrt::wait();
399     EXPECT_EQ(acc, (M * N + J));
400     delete lock;
401 }
402 
403 HWTEST_F(SyncTest, conditionTestWaitfor, TestSize.Level1)
404 {
405     ffrt::condition_variable cond;
406     std::atomic_int a = 0;
407     ffrt::mutex lock_;
408 
409     ffrt::submit(
__anon2aac0dff3702() 410         [&]() {
411             std::unique_lock lck(lock_);
412             cond.wait_for(lck, 100ms, [&] { return a == 1; });
413             EXPECT_EQ(a, 2);
414         },
__anon2aac0dff3a02() 415         {}, {});
416     ffrt::submit(
__anon2aac0dff3b02() 417         [&]() {
418             std::unique_lock lck(lock_);
419             cond.wait_for(lck, 150ms, [&] { return a == 2; });
420             EXPECT_EQ(a, 2);
421         },
__anon2aac0dff3d02() 422         {}, {});
423     ffrt::submit(
__anon2aac0dff3f02() 424         [&]() {
425             std::unique_lock lck(lock_);
426             a = 2;
427             cond.notify_all();
428         },
__anon2aac0dff4102() 429         {}, {});
430     ffrt::wait();
431 }
432 
433 HWTEST_F(SyncTest, conditionTestDataRace, TestSize.Level1)
434 {
435     std::atomic_bool exit {false};
436     ffrt::mutex mtx;
437     ffrt::condition_variable cv;
438     std::atomic_bool start {false};
439 
__anon2aac0dff4202null440     ffrt::thread th {[&] {
441         while (!exit) {
442             if (start) {
443                 cv.notify_one();
444                 ffrt::this_task::sleep_for(1us);
445             }
446         }
447     }};
448 
449     start = true;
450     for (int i = 0; i < 2000; ++i) {
451         std::unique_lock lk(mtx);
452         cv.wait_for(lk, 1us);
453     }
454     exit = true;
455     th.join();
456     exit = false;
457     start = true;
__anon2aac0dff4302null458     ffrt::thread th1 {[&] {
459         for (int i = 0; i < 2000; ++i) {
460             std::unique_lock lk(mtx);
461             cv.wait_for(lk, 1us);
462         }
463         exit = true;
464     }};
465 
466     while (!exit) {
467         if (start) {
468             cv.notify_one();
469             ffrt::this_task::sleep_for(1us);
470         }
471     }
472 
473     th1.join();
474 }
475 
NotifyOneTest(ffrt::mutex & mtx,ffrt::condition_variable & cv)476 static void NotifyOneTest(ffrt::mutex& mtx, ffrt::condition_variable& cv)
477 {
478     FFRT_LOGE("[RUN ] notifyone");
479     int value = 0;
480     bool flag {false};
481     ffrt::submit(
482         [&]() {
483             std::unique_lock lk(mtx);
484             cv.wait(lk, [&] { return flag; });
485             EXPECT_TRUE(lk.owns_lock());
486             value = 123;
487         },
488         {}, {});
489 
490     EXPECT_EQ(value, 0);
491 
492     ffrt::submit(
493         [&]() {
494             {
495                 std::unique_lock lk(mtx);
496                 flag = true;
497             }
498             cv.notify_one();
499         },
500         {}, {});
501 
502     ffrt::wait();
503 
504     EXPECT_EQ(value, 123);
505 }
506 
WaitUntilTimeoutTest(ffrt::mutex & mtx,ffrt::condition_variable & cv)507 static void WaitUntilTimeoutTest(ffrt::mutex& mtx, ffrt::condition_variable& cv)
508 {
509     constexpr auto eps = 3ms;
510 
511     FFRT_LOGE("[RUN ] WaitUntil timeout&notifyone");
512     int value = 0;
513     ffrt::submit(
514         [&]() {
515             std::unique_lock lk(mtx);
516             EXPECT_EQ(static_cast<int>(cv.wait_until(lk, std::chrono::steady_clock::now() + 30ms)),
517                 static_cast<int>(ffrt::cv_status::timeout));
518             EXPECT_TRUE(lk.owns_lock());
519             value = 123;
520         },
521         {}, {});
522 
523     EXPECT_EQ(value, 0);
524 
525     ffrt::submit(
526         [&]() {
527             ffrt::this_task::sleep_for(30ms + eps);
528             cv.notify_one();
529         },
530         {}, {});
531 
532     ffrt::wait();
533 
534     EXPECT_EQ(value, 123);
535 }
536 
WaitUtilFlagTest_1(ffrt::mutex & mtx,ffrt::condition_variable & cv)537 static void WaitUtilFlagTest_1(ffrt::mutex& mtx, ffrt::condition_variable& cv)
538 {
539     constexpr auto eps = 3ms;
540 
541     FFRT_LOGE("[RUN ] WaitUntil flag&notifyone");
542     int value = 0;
543     bool flag {false};
544 
545     ffrt::submit(
546         [&]() {
547             std::unique_lock lk(mtx);
548             EXPECT_TRUE(!cv.wait_until(lk, std::chrono::steady_clock::now() + 30ms, [&] { return flag; }));
549             value = 123;
550         },
551         {}, {});
552 
553     EXPECT_EQ(value, 0);
554 
555     ffrt::submit(
556         [&]() {
557             ffrt::this_task::sleep_for(30ms + eps);
558             cv.notify_one();
559         },
560         {}, {});
561 
562     ffrt::wait();
563 
564     EXPECT_EQ(value, 123);
565 }
566 
WaitUtilFlagTest_2(ffrt::mutex & mtx,ffrt::condition_variable & cv)567 static void WaitUtilFlagTest_2(ffrt::mutex& mtx, ffrt::condition_variable& cv)
568 {
569     int value = 0;
570     bool flag {false};
571 
572     ffrt::submit(
573         [&]() {
574             std::unique_lock lk(mtx);
575             EXPECT_TRUE(cv.wait_until(lk, std::chrono::steady_clock::now() + 30ms, [&] { return flag; }));
576             value = 123;
577         },
578         {}, {});
579 
580     EXPECT_EQ(value, 0);
581 
582     ffrt::submit(
583         [&]() {
584             std::unique_lock lk(mtx);
585             flag = true;
586             cv.notify_one();
587         },
588         {}, {});
589 
590     ffrt::wait();
591 
592     EXPECT_EQ(value, 123);
593 }
594 
WaitForTest_1(ffrt::mutex & mtx,ffrt::condition_variable & cv)595 static void WaitForTest_1(ffrt::mutex& mtx, ffrt::condition_variable& cv)
596 {
597     constexpr auto eps = 3ms;
598 
599     int value = 0;
600     ffrt::submit(
601         [&]() {
602             std::unique_lock lk(mtx);
603             EXPECT_EQ(static_cast<int>(cv.wait_for(lk, 30ms)), static_cast<int>(ffrt::cv_status::timeout));
604             EXPECT_TRUE(lk.owns_lock());
605             value = 123;
606         },
607         {}, {});
608 
609     EXPECT_EQ(value, 0);
610 
611     ffrt::submit(
612         [&]() {
613             ffrt::this_task::sleep_for(30ms + eps);
614             cv.notify_one();
615         },
616         {}, {});
617 
618     ffrt::wait();
619 
620     EXPECT_EQ(value, 123);
621 }
622 
WaitForTest_2(ffrt::mutex & mtx,ffrt::condition_variable & cv)623 static void WaitForTest_2(ffrt::mutex& mtx, ffrt::condition_variable& cv)
624 {
625     int value = 0;
626     ffrt::submit(
627         [&]() {
628             std::unique_lock lk(mtx);
629             ffrt::submit(
630                 [&]() {
631                     std::unique_lock lk(mtx);
632                     cv.notify_one();
633                 },
634                 {}, {});
635             EXPECT_EQ(static_cast<int>(cv.wait_for(lk, 30ms)), static_cast<int>(ffrt::cv_status::no_timeout));
636             EXPECT_EQ(value, 0);
637             EXPECT_TRUE(lk.owns_lock());
638             value = 123;
639         },
640         {}, {});
641 
642     ffrt::wait();
643 
644     EXPECT_EQ(value, 123);
645 }
646 
WaitForTest_3(ffrt::mutex & mtx,ffrt::condition_variable & cv)647 static void WaitForTest_3(ffrt::mutex& mtx, ffrt::condition_variable& cv)
648 {
649     constexpr auto eps = 3ms;
650 
651     int value = 0;
652     bool flag {false};
653 
654     ffrt::submit(
655         [&]() {
656             std::unique_lock lk(mtx);
657             EXPECT_TRUE(!cv.wait_for(lk, 30ms, [&] { return flag; }));
658             value = 123;
659         },
660         {}, {});
661 
662     EXPECT_EQ(value, 0);
663 
664     ffrt::submit(
665         [&]() {
666             ffrt::this_task::sleep_for(30ms + eps);
667             cv.notify_one();
668         },
669         {}, {});
670 
671     ffrt::wait();
672 
673     EXPECT_EQ(value, 123);
674 }
675 
WaitForTest_4(ffrt::mutex & mtx,ffrt::condition_variable & cv)676 static void WaitForTest_4(ffrt::mutex& mtx, ffrt::condition_variable& cv)
677 {
678     int value = 0;
679     bool flag {false};
680 
681     ffrt::submit(
682         [&]() {
683             std::unique_lock lk(mtx);
684             EXPECT_TRUE(cv.wait_for(lk, 30ms, [&] { return flag; }));
685             value = 123;
686         },
687         {}, {});
688 
689     EXPECT_EQ(value, 0);
690 
691     ffrt::submit(
692         [&]() {
693             std::unique_lock lk(mtx);
694             flag = true;
695             cv.notify_one();
696         },
697         {}, {});
698 
699     ffrt::wait();
700 
701     EXPECT_EQ(value, 123);
702 }
703 
LockTest(ffrt::shared_mutex & smtx)704 static void LockTest(ffrt::shared_mutex& smtx)
705 {
706     int x = 0;
707     const int N = 100;
708     const int R = 200;
709 
710     ffrt::submit(
711         [&]() {
712             for (int i = 0; i < N; i++) {
713                 smtx.lock();
714                 x++;
715                 smtx.unlock();
716             }
717         },
718         {}, {});
719 
720     for (int j = 0; j < N; ++j) {
721         smtx.lock();
722         x++;
723         smtx.unlock();
724     }
725 
726     ffrt::wait();
727     EXPECT_EQ(x, R);
728 }
729 
TryLockTest(ffrt::shared_mutex & smtx)730 static void TryLockTest(ffrt::shared_mutex& smtx)
731 {
732     int x = 0;
733     const int N = 100;
734     ffrt::submit(
735         [&]() {
736             smtx.lock();
737             ffrt::this_task::sleep_for(20ms);
738             smtx.unlock();
739         },
740         {}, {});
741 
742     ffrt::this_task::sleep_for(2ms);
743 
744     bool ret = smtx.try_lock();
745     EXPECT_EQ(ret, false);
746     if (ret) {
747         smtx.unlock();
748     }
749     ffrt::wait();
750 
751     ret = smtx.try_lock();
752     EXPECT_EQ(ret, true);
753     if (ret) {
754         smtx.unlock();
755     }
756 }
757 
LockSharedTest(ffrt::shared_mutex & smtx)758 static void LockSharedTest(ffrt::shared_mutex& smtx)
759 {
760     int x = 0;
761     const int N = 100;
762 
763     ffrt::submit(
764         [&]() {
765             smtx.lock_shared();
766             ffrt::this_task::sleep_for(20ms);
767             x = N;
768             smtx.unlock_shared();
769         },
770         {}, {});
771     ffrt::this_task::sleep_for(2ms);
772 
773     smtx.lock_shared();
774     EXPECT_EQ(x, 0);
775     smtx.unlock_shared();
776 
777     smtx.lock();
778     EXPECT_EQ(x, N);
779     smtx.unlock();
780 
781     ffrt::wait();
782 
783     smtx.lock_shared();
784     EXPECT_EQ(x, N);
785     smtx.unlock_shared();
786 }
787 
TryLockSharedTest(ffrt::shared_mutex & smtx)788 static void TryLockSharedTest(ffrt::shared_mutex& smtx)
789 {
790     int x = 0;
791     const int N = 100;
792 
793     ffrt::submit(
794         [&]() {
795             smtx.lock_shared();
796             ffrt::this_task::sleep_for(20ms);
797             x = N;
798             smtx.unlock_shared();
799         },
800         {}, {});
801     ffrt::this_task::sleep_for(2ms);
802 
803     bool ret = smtx.try_lock_shared();
804     EXPECT_EQ(ret, true);
805     EXPECT_EQ(x, 0);
806     if (ret) {
807         smtx.unlock_shared();
808     }
809     ffrt::wait();
810 
811     ret = smtx.try_lock_shared();
812     EXPECT_EQ(ret, true);
813     EXPECT_EQ(x, N);
814     if (ret) {
815         smtx.unlock_shared();
816     }
817 
818     ffrt::submit(
819         [&]() {
820             smtx.lock();
821             ffrt::this_task::sleep_for(20ms);
822             x = 0;
823             smtx.unlock();
824         },
825         {}, {});
826     ffrt::this_task::sleep_for(2ms);
827 
828     ret = smtx.try_lock_shared();
829     EXPECT_EQ(ret, false);
830     EXPECT_EQ(x, N);
831     if (ret) {
832         smtx.unlock_shared();
833     }
834     ffrt::wait();
835 
836     ret = smtx.try_lock_shared();
837     EXPECT_EQ(ret, true);
838     EXPECT_EQ(x, 0);
839     if (ret) {
840         smtx.unlock_shared();
841     }
842 }
843 
844 HWTEST_F(SyncTest, thread1, TestSize.Level1)
845 {
__anon2aac0dff8802(int a, const int& b) 846     auto ThreadFunc1 = [](int a, const int& b) {
847         FFRT_LOGW("a = %d, b = %d", a, b);
848         return 0;
849     };
850 
__anon2aac0dff8902(const char* a, const char* b) 851     auto ThreadFunc2 = [](const char* a, const char* b) {
852         FFRT_LOGW("%s %s", a, b);
853         return 0;
854     };
855 
856     {
857         int value = 0;
__anon2aac0dff8a02null858         std::thread th0 {[&value, &ThreadFunc1, &ThreadFunc2] {
859             std::thread th1 {ThreadFunc1, 10, 20};
860             std::thread th2 {ThreadFunc2, "hello", "ffrt"};
861             th1.join();
862             th2.join();
863 
864             value = 123;
865             FFRT_LOGW("value = %d", value);
866         }};
867         th0.join();
868         assert(!th0.joinable());
869         EXPECT_EQ(value, 123);
870     }
871     {
872         int value = 0;
__anon2aac0dff8b02null873         ffrt::thread th0 {[&value, &ThreadFunc1, &ThreadFunc2] {
874             ffrt::thread th1 {ThreadFunc1, 10, 20};
875             ffrt::thread th2 {ThreadFunc2, "hello", "ffrt"};
876             th1.join();
877             th2.join();
878 
879             value = 123;
880             FFRT_LOGW("value = %d", value);
881         }};
882         th0.join();
883         assert(!th0.joinable());
884         EXPECT_EQ(value, 123);
885     }
886 }
887 
f1(int n)888 void f1(int n)
889 {
890     for (int i = 0; i < 5; ++i) {
891         std::cout << "Thread 1 executing\n";
892         ++n;
893         std::this_thread::sleep_for(std::chrono::milliseconds(10));
894     }
895 }
896 
f2(int & n)897 void f2(int& n)
898 {
899     for (int i = 0; i < 5; ++i) {
900         std::cout << "Thread 2 executing\n";
901         ++n;
902         std::this_thread::sleep_for(std::chrono::milliseconds(10));
903     }
904 }
905 
906 class foo {
907 public:
bar()908     void bar()
909     {
910         for (int i = 0; i < 5; ++i) {
911             std::cout << "Thread 3 executing\n";
912             ++n;
913             std::this_thread::sleep_for(std::chrono::milliseconds(10));
914         }
915     }
916     int n = 0;
917 };
918 
919 class baz {
920 public:
operator ()()921     void operator()()
922     {
923         for (int i = 0; i < 5; ++i) {
924             std::cout << "Thread 4 executing\n";
925             ++n;
926             std::this_thread::sleep_for(std::chrono::milliseconds(10));
927         }
928     }
929     int n = 0;
930 };
931 
932 HWTEST_F(SyncTest, thread2, TestSize.Level1)
933 {
934     {
935         int n = 0;
936         foo f;
937         baz b;
938         {
939             std::thread t2(f1, n + 1);
940             t2.detach(); // test detach
941         }
942         std::thread t1; // t1 is not a thread
943         std::thread t2(f1, n + 1); // pass by value
944         std::thread t3(f2, std::ref(n)); // pass by reference
945         std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
946         std::thread t5(&foo::bar, &f); // t5 runs foo::bar() on object f
947         std::thread t6(b); // t6 runs baz::operator() on a copy of object b
948         EXPECT_EQ(t1.joinable(), false);
949         EXPECT_EQ(t2.joinable(), true);
950         t2.join();
951         EXPECT_EQ(t2.joinable(), false);
952         t4.join();
953         t5.join();
954         t6.join();
955         EXPECT_EQ(n, 5);
956         EXPECT_EQ(f.n, 5);
957         EXPECT_EQ(b.n, 0);
958     }
959     FFRT_LOGW("ffrt version");
960     {
961         int n = 0;
962         foo f;
963         baz b;
964         {
965             ffrt::thread t2(f1, n + 1);
966             t2.detach(); // test detach
967         }
968         ffrt::thread t1; // t1 is not a thread
969         ffrt::thread t2(f1, n + 1); // pass by value
970         ffrt::thread t3(f2, std::ref(n)); // pass by reference
971         ffrt::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
972         ffrt::thread t5(&foo::bar, &f); // t5 runs foo::bar() on object f
973         ffrt::thread t6(b); // t6 runs baz::operator() on a copy of object b
974         EXPECT_EQ(t1.joinable(), false);
975         EXPECT_EQ(t2.joinable(), true);
976         t2.join();
977         EXPECT_EQ(t2.joinable(), false);
978         EXPECT_EQ(t3.joinable(), false);
979         EXPECT_EQ(t4.joinable(), true);
980         t4.join();
981         EXPECT_EQ(t4.joinable(), false);
982         t5.join();
983         t6.join();
984         EXPECT_EQ(n, 5);
985         EXPECT_EQ(f.n, 5);
986         EXPECT_EQ(b.n, 0);
987     }
988 }
989 
990 HWTEST_F(SyncTest, thread_with_qos, TestSize.Level1)
991 {
992     int a = 0;
__anon2aac0dff8c02null993     auto task = [&] {
994         a++;
995     };
996     ffrt::thread(static_cast<int>(ffrt::qos_user_initiated), task).join();
997     EXPECT_EQ(1, a);
998 }
999 
1000 HWTEST_F(SyncTest, thread_with_name, TestSize.Level1)
1001 {
1002     int a = 0;
__anon2aac0dff8d02null1003     auto task = [&] {
1004         a++;
1005     };
1006     std::string name = "thread_test";
1007     ffrt::thread(name.c_str(), static_cast<int>(ffrt::qos_user_initiated), task).join();
1008     EXPECT_EQ(1, a);
1009 }
1010 
1011 struct F {
1012     template<typename T, typename U>
operator ()F1013     void operator()(T, U, int& a)
1014     {
1015         using std::is_same;
1016         using std::reference_wrapper;
1017         static_assert(is_same<T, reference_wrapper<int>>::value, "");
1018         static_assert(is_same<U, reference_wrapper<const int>>::value, "");
1019         a++;
1020     }
1021 };
1022 
1023 HWTEST_F(SyncTest, thread_with_ref_check, TestSize.Level1)
1024 {
1025     int a = 0;
1026     ffrt::thread t(F{}, std::ref(a), std::cref(a), std::ref(a));
1027     t.join();
1028     EXPECT_EQ(1, a);
1029 }
1030 
1031 struct A {
1032     A() = default;
1033     explicit A(const A&) = default;
1034 };
1035 
func(const A &)1036 void func(const A&) { }
1037 
1038 HWTEST_F(SyncTest, thread_with_ref, TestSize.Level1)
1039 {
1040     ffrt::thread t(func, A{});
1041     t.join();
1042 }
1043 
1044 HWTEST_F(SyncTest, future_wait, TestSize.Level1)
1045 {
__anon2aac0dff8e02null1046     ffrt::packaged_task<int()> task([] { return 7; });
1047     ffrt::future<int> f1 = task.get_future();
1048     ffrt::thread t(std::move(task));
1049 
__anon2aac0dff8f02null1050     ffrt::future<int> f2 = ffrt::async([] { return 8; });
1051 
1052     ffrt::promise<int> p;
1053     ffrt::promise<int> p1;
1054     p1 = std::move(p);
1055     ffrt::future<int> f3 = p1.get_future();
1056     ffrt::future<int> f4;
1057     f4 = std::move(f3);
__anon2aac0dff9002null1058     ffrt::thread([&p1] { p1.set_value(9); }).detach();
1059 
1060     std::cout << "Waiting..." << std::flush;
1061     f1.wait();
1062     f2.wait();
1063     f4.wait();
1064     std::cout << "Done!\nResults are: "
1065               << f1.get() << ' ' << f2.get() << ' ' << f4.get() << '\n';
1066     t.join();
1067 }
1068 
1069 HWTEST_F(SyncTest, future_wait_void, TestSize.Level1)
1070 {
1071     vector<int> result(3, 0);
__anon2aac0dff9102null1072     ffrt::packaged_task<void()> task([&] { result[0] = 1; });
1073     ffrt::future<void> f1 = task.get_future();
1074     ffrt::thread t(std::move(task));
1075     ffrt::thread t1;
1076     t1 = std::move(t);
1077 
__anon2aac0dff9202null1078     ffrt::future<void> f2 = ffrt::async([&] { result[1] = 2; });
1079 
1080     ffrt::promise<void> p;
1081     ffrt::future<void> f3 = p.get_future();
1082     ffrt::promise<void> p1;
1083     ffrt::future<void> f4;
1084     p1 = std::move(p);
1085     f4 = std::move(f3);
__anon2aac0dff9302null1086     ffrt::thread([&] { result[2] = 3; p1.set_value(); }).detach();
1087 
1088     f1.wait();
1089     f2.wait();
1090     f4.wait();
1091     EXPECT_EQ(result[0], 1);
1092     EXPECT_EQ(result[1], 2);
1093     EXPECT_EQ(result[2], 3);
1094     t1.join();
1095 }