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 <gtest/gtest.h>
17 #include <chrono>
18 #include "c/thread.h"
19 #include "ffrt_inner.h"
20 #include "../common.h"
21 
22 using namespace ffrt;
23 using namespace std;
24 using namespace testing;
25 #ifdef HWTEST_TESTING_EXT_ENABLE
26 using namespace testing::ext;
27 #endif
28 
29 class CVTest : public testing::Test {
30 protected:
SetUpTestCase()31     static void SetUpTestCase()
32     {
33     }
34 
TearDownTestCase()35     static void TearDownTestCase()
36     {
37     }
38 
SetUp()39     virtual void SetUp()
40     {
41     }
42 
TearDown()43     virtual void TearDown()
44     {
45     }
46 };
47 
48 HWTEST_F(CVTest, conditonV_notify_one_test, TestSize.Level1)
49 {
50     ffrt::condition_variable cond;
51     int a = 0;
52     ffrt::mutex lock_;
53 
54     ffrt::submit(
__anone2a138be0102() 55         [&]() {
56             std::unique_lock lck(lock_);
57             cond.wait(lck, [&] { return a == 1; });
58         },
__anone2a138be0302() 59         {}, {});
60 
61     ffrt::submit(
__anone2a138be0502() 62         [&]() {
63             std::unique_lock lck(lock_);
64             a = 1;
65             cond.notify_one();
66         },
__anone2a138be0602() 67         {}, {});
68     ffrt::wait();
69 }
70 
71 HWTEST_F(CVTest, conditonV_notify_all_test, TestSize.Level1)
72 {
73     ffrt::condition_variable cond;
74     int a = 0;
75     ffrt::mutex lock_;
76 
77     ffrt::submit(
__anone2a138be0802() 78         [&]() {
79             std::unique_lock lck(lock_);
80             cond.wait(lck, [&] { return a == 1; });
81         },
__anone2a138be0a02() 82         {}, {});
83     ffrt::submit(
__anone2a138be0c02() 84         [&]() {
85             std::unique_lock lck(lock_);
86             cond.wait(lck, [&] { return a == 1; });
87         },
__anone2a138be0e02() 88         {}, {});
89 
90     ffrt::submit(
__anone2a138be1002() 91         [&]() {
92             std::unique_lock lck(lock_);
93             a = 1;
94             cond.notify_all();
95         },
__anone2a138be1102() 96         {}, {});
97 
98     ffrt::wait();
99 }
100 
101 HWTEST_F(CVTest, conditonV_wait_for_test, TestSize.Level1)
102 {
103     ffrt::condition_variable cond;
104     std::atomic_int a = 0;
105     ffrt::mutex lock_;
106 
107     ffrt::submit(
__anone2a138be1302() 108         [&]() {
109             std::unique_lock lck(lock_);
110             cond.wait_for(lck, 100ms, [&] { return a == 1; });
111             EXPECT_EQ(a, 2);
112         },
__anone2a138be1602() 113         {}, {});
114 
115     ffrt::submit(
__anone2a138be1702() 116         [&]() {
117                 std::unique_lock lck(lock_);
118                 a = 2;
119                 cond.notify_one();
120             },
__anone2a138be1802() 121         {}, {});
122 
123     ffrt::wait();
124 }
125 
126 HWTEST_F(CVTest, conditonV_wait_for_test2, TestSize.Level1)
127 {
128     ffrt::condition_variable cond;
129     ffrt::mutex lock_;
130     ffrt::cv_status status;
131 
132     ffrt::submit(
__anone2a138be1a02() 133         [&]() {
134             std::unique_lock lck(lock_);
135             status = cond.wait_for(lck, 100ms);
136             EXPECT_EQ(status, ffrt::cv_status::timeout);
137         },
__anone2a138be1c02() 138         {}, {});
139 
140     ffrt::wait();
141 }
142 
143 HWTEST_F(CVTest, conditonV_wait_for_test3, TestSize.Level1)
144 {
145     ffrt::condition_variable cond;
146     ffrt::mutex lock_;
147     ffrt::cv_status status;
148 
149     std::unique_lock lck(lock_);
150     status = cond.wait_for(lck, 100ms);
151     EXPECT_EQ(status, ffrt::cv_status::timeout);
152 }
153 
154 HWTEST_F(CVTest, conditonV_nullptr_test, TestSize.Level1)
155 {
156     int ret = 0;
157 
158     ret = ffrt_cond_init(nullptr, nullptr);
159     EXPECT_NE(ret, 0);
160     ret = ffrt_cond_signal(nullptr);
161     EXPECT_NE(ret, 0);
162     ret = ffrt_cond_broadcast(nullptr);
163     EXPECT_NE(ret, 0);
164     ret = ffrt_cond_wait(nullptr, nullptr);
165     EXPECT_NE(ret, 0);
166     ret = ffrt_cond_timedwait(nullptr, nullptr, nullptr);
167     EXPECT_NE(ret, 0);
168     ffrt_cond_destroy(nullptr);
169 }
170 
171 class MutexTest : public testing::Test {
172 protected:
SetUpTestCase()173     static void SetUpTestCase()
174     {
175     }
176 
TearDownTestCase()177     static void TearDownTestCase()
178     {
179     }
180 
SetUp()181     virtual void SetUp()
182     {
183     }
184 
TearDown()185     virtual void TearDown()
186     {
187     }
188 };
189 
190 HWTEST_F(MutexTest, try_lock_test, TestSize.Level1)
191 {
192     int val = -1;
193     ffrt::mutex lock;
194     lock.lock();
195     val = lock.try_lock();
196     EXPECT_EQ(val, 0);
197     lock.unlock();
198     val = lock.try_lock();
199     EXPECT_EQ(val, 1);
200     lock.unlock();
201     lock.unlock();
202 }
203 
204 HWTEST_F(MutexTest, lock_stress_test, TestSize.Level1)
205 {
206     // trigger lazy init
__anone2a138be1f02() 207     ffrt::submit([&]() {}, {}, {});
208     ffrt::wait();
209 
210     const int N = 10;
211     const int M = 10;
212     const int J = 10;
213     ffrt::mutex lock;
214     // std::mutex lock;
215     int acc = 0;
216     for (int i = 0; i < N; ++i) {
217     ffrt::submit(
__anone2a138be2002() 218         [&]() {
219         for (int j = 0; j < M; ++j) {
220             lock.lock();
221             acc++;
222             lock.unlock();
223         }
224         },
__anone2a138be2202() 225         {}, {});
226     }
227 
228     for (int j = 0; j < J; ++j) {
229     lock.lock();
230     acc++;
231     lock.unlock();
232     }
233 
234     ffrt::wait();
235     EXPECT_EQ(acc, (M * N + J));
236 }
237 
238 class SleepTest : public testing::Test {
239 protected:
SetUpTestCase()240     static void SetUpTestCase()
241     {
242     }
243 
TearDownTestCase()244     static void TearDownTestCase()
245     {
246     }
247 
SetUp()248     virtual void SetUp()
249     {
250     }
251 
TearDown()252     virtual void TearDown()
253     {
254     }
255 };
256 
257 HWTEST_F(SleepTest, yield_test, TestSize.Level1)
258 {
259     int a = 0;
260 
261     this_task::yield();
262 
263     EXPECT_EQ(a, 0);
264 }
265 
266 HWTEST_F(SleepTest, sleep_for_test1, TestSize.Level1)
267 {
268     int a = 0;
269 
270     this_task::sleep_for(10ms);
271 
272     EXPECT_EQ(a, 0);
273 }
274 
275 HWTEST_F(SleepTest, sleep_for_test2, TestSize.Level1)
276 {
277     int a = 0;
278 
__anone2a138be2302() 279     submit([&]() {
280         this_task::sleep_for(5us);
281         a = 2;
282         }, {}, {});
283 
284     wait();
285 
286     EXPECT_EQ(a, 2);
287 }
288 
thd_func(void * arg)289 void* thd_func(void *arg)
290 {
291     int *counter = (int *)arg;
292     (*counter)++;
293     return arg;
294 }
295 
296 HWTEST_F(SleepTest, thread_test, TestSize.Level1)
297 {
298     int a = 0;
299     ffrt_thread_t thread;
300     ffrt_thread_create(&thread, nullptr, thd_func, &a);
301     void* result = nullptr;
302     ffrt_thread_join(thread, &result);
303     EXPECT_EQ(1, a);
304     EXPECT_EQ(&a, result);
305 }
306