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