1 /*
2 * Copyright (c) 2021 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 <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <time.h>
20 #include <unistd.h>
21 #include <pthread.h>
22 #include <sys/time.h>
23 #include <gtest/gtest.h>
24 #include "utils.h"
25 #include "mt_utils.h"
26 #include "log.h"
27 #include "FutexTest.h"
28
29 using namespace testing::ext;
30
31 /********************************************* Test case dividing line ***********************************************/
32
33 pthread_rwlock_t g_rwlock1;
34
PthreadRWlockWW1(void * arg)35 void *PthreadRWlockWW1(void *arg)
36 {
37 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock1), 0) << "> return errno";
38 Msleep(50);
39 CheckStep(2);
40 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock1), 0) << "> return errno";
41 return arg;
42 }
43
PthreadRWlockWW2(void * arg)44 void *PthreadRWlockWW2(void *arg)
45 {
46 Msleep(20);
47 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock1), 0) << "> return errno";
48 CheckStep(3);
49 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock1), 0) << "> return errno";
50 return arg;
51 }
52
53 /**
54 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0100
55 * @tc.name test rdlock and wrlock, write - write
56 * @tc.desc [C- SOFTWARE -0200]
57 */
58 HWTEST_F(FutexTest, testPthreadRWlockWW, Function | MediumTest | Level3)
59 {
60 pthread_t tid[2];
61 CheckStep(1);
62 EXPECT_EQ(pthread_rwlock_init(&g_rwlock1, nullptr), 0);
63
64 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockWW1, nullptr), 0) << "> return errno";
65 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockWW2, nullptr), 0) << "> return errno";
66
67 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
68 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
69 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
70 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock1), 0);
71 }
72
73 /********************************************* Test case dividing line ***********************************************/
74
75 pthread_rwlock_t g_rwlock2;
76
PthreadRWlockWR1(void * arg)77 void *PthreadRWlockWR1(void *arg)
78 {
79 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock2), 0) << "> return errno";
80 Msleep(50);
81 CheckStep(2);
82 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock2), 0) << "> return errno";
83 return arg;
84 }
85
PthreadRWlockWR2(void * arg)86 void *PthreadRWlockWR2(void *arg)
87 {
88 Msleep(20);
89 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock2), 0) << "> return errno";
90 CheckStep(3);
91 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock2), 0) << "> return errno";
92 return arg;
93 }
94
95 /**
96 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0200
97 * @tc.name test rdlock and wrlock, write - read
98 * @tc.desc [C- SOFTWARE -0200]
99 */
100 HWTEST_F(FutexTest, testPthreadRWlockWR, Function | MediumTest | Level3)
101 {
102 pthread_t tid[2];
103 CheckStep(1);
104 EXPECT_EQ(pthread_rwlock_init(&g_rwlock2, nullptr), 0);
105
106 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockWR1, nullptr), 0) << "> return errno";
107 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockWR2, nullptr), 0) << "> return errno";
108
109 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
110 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
111 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
112 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock2), 0);
113 }
114
115 /********************************************* Test case dividing line ***********************************************/
116
117 pthread_rwlock_t g_rwlock3;
118
PthreadRWlockRR1(void * arg)119 void *PthreadRWlockRR1(void *arg)
120 {
121 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock3), 0) << "> return errno";
122 Msleep(50);
123 CheckStep(3);
124 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock3), 0) << "> return errno";
125 return arg;
126 }
127
PthreadRWlockRR2(void * arg)128 void *PthreadRWlockRR2(void *arg)
129 {
130 Msleep(20);
131 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock3), 0) << "> return errno";
132 CheckStep(2);
133 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock3), 0) << "> return errno";
134 return arg;
135 }
136
137 /**
138 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0300
139 * @tc.name test rdlock and wrlock, read - read
140 * @tc.desc [C- SOFTWARE -0200]
141 */
142 HWTEST_F(FutexTest, testPthreadRWlockRR, Function | MediumTest | Level3)
143 {
144 pthread_t tid[2];
145 CheckStep(1);
146 EXPECT_EQ(pthread_rwlock_init(&g_rwlock3, nullptr), 0);
147
148 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockRR1, nullptr), 0) << "> return errno";
149 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockRR2, nullptr), 0) << "> return errno";
150
151 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
152 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
153 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
154 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock3), 0);
155 }
156
157 /********************************************* Test case dividing line ***********************************************/
158
159 pthread_rwlock_t g_rwlock4;
160
PthreadRWlockRW1(void * arg)161 void *PthreadRWlockRW1(void *arg)
162 {
163 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock4), 0) << "> return errno";
164 Msleep(50);
165 CheckStep(2);
166 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock4), 0) << "> return errno";
167 return arg;
168 }
169
PthreadRWlockRW2(void * arg)170 void *PthreadRWlockRW2(void *arg)
171 {
172 Msleep(20);
173 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock4), 0) << "> return errno";
174 CheckStep(3);
175 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock4), 0) << "> return errno";
176 return arg;
177 }
178
179 /**
180 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0400
181 * @tc.name test rdlock and wrlock, read - write
182 * @tc.desc [C- SOFTWARE -0200]
183 */
184 HWTEST_F(FutexTest, testPthreadRWlockRW, Function | MediumTest | Level3)
185 {
186 pthread_t tid[2];
187 CheckStep(1);
188 EXPECT_EQ(pthread_rwlock_init(&g_rwlock4, nullptr), 0);
189
190 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockRW1, nullptr), 0) << "> return errno";
191 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockRW2, nullptr), 0) << "> return errno";
192
193 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
194 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
195 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
196 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock4), 0);
197 }
198
199 /********************************************* Test case dividing line ***********************************************/
200
201 pthread_rwlock_t g_rwlock5;
202
PthreadRWtrylockWR1(void * arg)203 void *PthreadRWtrylockWR1(void *arg)
204 {
205 EXPECT_EQ(pthread_rwlock_trywrlock(&g_rwlock5), 0) << "> return errno";
206 Msleep(50);
207 CheckStep(3);
208 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock5), 0) << "> return errno";
209 return arg;
210 }
211
PthreadRWtrylockWR2(void * arg)212 void *PthreadRWtrylockWR2(void *arg)
213 {
214 Msleep(20);
215 EXPECT_EQ(pthread_rwlock_tryrdlock(&g_rwlock5), EBUSY) << "> should return EBUSY";
216 CheckStep(2);
217 return arg;
218 }
219
220 /**
221 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0500
222 * @tc.name test tryrdlock and trywrlock, write - read
223 * @tc.desc [C- SOFTWARE -0200]
224 */
225 HWTEST_F(FutexTest, testPthreadRWtrylockWR, Function | MediumTest | Level3)
226 {
227 pthread_t tid[2];
228 CheckStep(1);
229 EXPECT_EQ(pthread_rwlock_init(&g_rwlock5, nullptr), 0);
230
231 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWtrylockWR1, nullptr), 0) << "> return errno";
232 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWtrylockWR2, nullptr), 0) << "> return errno";
233
234 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
235 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
236 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
237 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock5), 0);
238 }
239
240 /********************************************* Test case dividing line ***********************************************/
241
242 pthread_rwlock_t g_rwlock6;
243
PthreadRWtrylockRW1(void * arg)244 void *PthreadRWtrylockRW1(void *arg)
245 {
246 EXPECT_EQ(pthread_rwlock_tryrdlock(&g_rwlock6), 0) << "> return errno";
247 Msleep(50);
248 CheckStep(3);
249 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock6), 0) << "> return errno";
250 return arg;
251 }
252
PthreadRWtrylockRW2(void * arg)253 void *PthreadRWtrylockRW2(void *arg)
254 {
255 Msleep(20);
256 EXPECT_EQ(pthread_rwlock_trywrlock(&g_rwlock6), EBUSY) << "> should return EBUSY";
257 CheckStep(2);
258 return arg;
259 }
260
261 /**
262 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0600
263 * @tc.name test tryrdlock and trywrlock, read - write
264 * @tc.desc [C- SOFTWARE -0200]
265 */
266 HWTEST_F(FutexTest, testPthreadRWtrylockRW, Function | MediumTest | Level3)
267 {
268 pthread_t tid[2];
269 CheckStep(1);
270 EXPECT_EQ(pthread_rwlock_init(&g_rwlock6, nullptr), 0);
271
272 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWtrylockRW1, nullptr), 0) << "> return errno";
273 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWtrylockRW2, nullptr), 0) << "> return errno";
274
275 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
276 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
277 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
278 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock6), 0);
279 }
280
281 /********************************************* Test case dividing line ***********************************************/
282
283 pthread_rwlock_t g_rwlock7;
284
PthreadTimdNoOutRWlockWR1(void * arg)285 void *PthreadTimdNoOutRWlockWR1(void *arg)
286 {
287 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock7), 0) << "> return errno";
288 Msleep(50);
289 CheckStep(2);
290 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock7), 0) << "> return errno";
291 return arg;
292 }
293
PthreadTimdNoOutRWlockWR2(void * arg)294 void *PthreadTimdNoOutRWlockWR2(void *arg)
295 {
296 struct timespec ts = {0};
297 Msleep(20);
298 GetDelayedTime(&ts, 100);
299 EXPECT_EQ(pthread_rwlock_timedrdlock(&g_rwlock7, &ts), 0) << "> return errno";
300 CheckStep(3);
301 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock7), 0) << "> return errno";
302 return arg;
303 }
304
305 /**
306 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0700
307 * @tc.name test pthread_rwlock_timedrdlock with no timeout , write - read
308 * @tc.desc [C- SOFTWARE -0200]
309 */
310 HWTEST_F(FutexTest, testPthreadTimdNoOutRWlockWR, Function | MediumTest | Level3)
311 {
312 pthread_t tid[2];
313 CheckStep(1);
314 EXPECT_EQ(pthread_rwlock_init(&g_rwlock7, nullptr), 0);
315
316 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdNoOutRWlockWR1, nullptr), 0) << "> return errno";
317 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdNoOutRWlockWR2, nullptr), 0) << "> return errno";
318
319 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
320 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
321 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
322 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock7), 0);
323 }
324
325 /********************************************* Test case dividing line ***********************************************/
326
327 pthread_rwlock_t g_rwlock8;
328
PthreadTimdOutRWlockWR1(void * arg)329 void *PthreadTimdOutRWlockWR1(void *arg)
330 {
331 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock8), 0) << "> return errno";
332 Msleep(50);
333 CheckStep(2);
334 Msleep(100);
335 CheckStep(4);
336 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock8), 0) << "> return errno";
337 return arg;
338 }
339
PthreadTimdOutRWlockWR2(void * arg)340 void *PthreadTimdOutRWlockWR2(void *arg)
341 {
342 struct timespec ts = {0};
343 struct timespec tsNow = {0};
344 Msleep(20);
345 GetDelayedTime(&ts, 100);
346 EXPECT_EQ(pthread_rwlock_timedrdlock(&g_rwlock8, &ts), ETIMEDOUT) << "> return errno";
347 CheckStep(3);
348 clock_gettime(CLOCK_REALTIME, &tsNow);
349 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
350 EXPECT_GE(timeDiff, 0);
351 EXPECT_LE(timeDiff, 20);
352 return arg;
353 }
354
355 /**
356 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0800
357 * @tc.name test pthread_rwlock_timedrdlock with timeout, write - read
358 * @tc.desc [C- SOFTWARE -0200]
359 */
360 HWTEST_F(FutexTest, testPthreadTimdOutRWlockWR, Function | MediumTest | Level3)
361 {
362 pthread_t tid[2];
363 CheckStep(1);
364 EXPECT_EQ(pthread_rwlock_init(&g_rwlock8, nullptr), 0);
365
366 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdOutRWlockWR1, nullptr), 0) << "> return errno";
367 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdOutRWlockWR2, nullptr), 0) << "> return errno";
368
369 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
370 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
371 EXPECT_EQ(CheckStep(5), (uint64_t)0x12345);
372 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock8), 0);
373 }
374
375 /********************************************* Test case dividing line ***********************************************/
376
377 pthread_rwlock_t g_rwlock9;
378
PthreadTimdOutRWlockWW1(void * arg)379 void *PthreadTimdOutRWlockWW1(void *arg)
380 {
381 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock9), 0) << "> return errno";
382 Msleep(50);
383 CheckStep(2);
384 Msleep(100);
385 CheckStep(4);
386 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock9), 0) << "> return errno";
387 return arg;
388 }
389
PthreadTimdOutRWlockWW2(void * arg)390 void *PthreadTimdOutRWlockWW2(void *arg)
391 {
392 struct timespec ts = {0};
393 struct timespec tsNow = {0};
394 Msleep(20);
395 GetDelayedTime(&ts, 100);
396 EXPECT_EQ(pthread_rwlock_timedwrlock(&g_rwlock9, &ts), ETIMEDOUT) << "> return errno";
397 CheckStep(3);
398 clock_gettime(CLOCK_REALTIME, &tsNow);
399 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
400 EXPECT_GE(timeDiff, 0);
401 EXPECT_LE(timeDiff, 20);
402 return arg;
403 }
404
405 /**
406 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0900
407 * @tc.name test pthread_rwlock_timedwrlock with timeout, write - write
408 * @tc.desc [C- SOFTWARE -0200]
409 */
410 HWTEST_F(FutexTest, testPthreadTimdOutRWlockWW, Function | MediumTest | Level3)
411 {
412 pthread_t tid[2];
413 CheckStep(1);
414 EXPECT_EQ(pthread_rwlock_init(&g_rwlock9, nullptr), 0);
415
416 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdOutRWlockWW1, nullptr), 0) << "> return errno";
417 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdOutRWlockWW2, nullptr), 0) << "> return errno";
418
419 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
420 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
421 EXPECT_EQ(CheckStep(5), (uint64_t)0x12345);
422 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock9), 0);
423 }
424
425 /********************************************* Test case dividing line ***********************************************/
426
427 pthread_rwlock_t g_rwlockA;
428
PthreadTimdNoOutRWlockWW1(void * arg)429 void *PthreadTimdNoOutRWlockWW1(void *arg)
430 {
431 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlockA), 0) << "> return errno";
432 Msleep(50);
433 CheckStep(2);
434 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlockA), 0) << "> return errno";
435 return arg;
436 }
437
PthreadTimdNoOutRWlockWW2(void * arg)438 void *PthreadTimdNoOutRWlockWW2(void *arg)
439 {
440 struct timespec ts = {0};
441 Msleep(20);
442 GetDelayedTime(&ts, 100);
443 EXPECT_EQ(pthread_rwlock_timedwrlock(&g_rwlockA, &ts), 0) << "> return errno";
444 CheckStep(3);
445 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlockA), 0) << "> return errno";
446 return arg;
447 }
448
449 /**
450 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_1000
451 * @tc.name test pthread_rwlock_timedwrlock with no timeout, write - write
452 * @tc.desc [C- SOFTWARE -0200]
453 */
454 HWTEST_F(FutexTest, testPthreadTimdNoOutRWlockWW, Function | MediumTest | Level3)
455 {
456 pthread_t tid[2];
457 CheckStep(1);
458 EXPECT_EQ(pthread_rwlock_init(&g_rwlockA, nullptr), 0);
459
460 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdNoOutRWlockWW1, nullptr), 0) << "> return errno";
461 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdNoOutRWlockWW2, nullptr), 0) << "> return errno";
462
463 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
464 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
465 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
466 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlockA), 0);
467 }
468
469 /********************************************* Test case dividing line ***********************************************/
470
471 /**
472 * @tc.number SUB_KERNEL_FUTEX_RWLOCKATTR_0100
473 * @tc.name test pthread_rwlockattr_init api
474 * @tc.desc [C- SOFTWARE -0200]
475 */
476 HWTEST_F(FutexTest, testPthreadRwlockAttr, Function | MediumTest | Level1)
477 {
478 pthread_rwlockattr_t attr;
479 EXPECT_EQ(pthread_rwlockattr_init(&attr), 0);
480 EXPECT_EQ(pthread_rwlockattr_destroy(&attr), 0);
481 }
482