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
ThreadMutex(void * arg)33 void *ThreadMutex(void *arg)
34 {
35 int delayTime = GetRandom(50);
36 pthread_mutex_t *mtx = (pthread_mutex_t *)arg;
37 EXPECT_EQ(pthread_mutex_lock(mtx), 0) << "> return errno";
38 CheckStep(1);
39 Msleep(delayTime);
40 EXPECT_EQ(CheckStep(2), (uint64_t)0x12);
41 EXPECT_EQ(pthread_mutex_unlock(mtx), 0) << "> return errno";
42 return arg;
43 }
44
45 /**
46 * @tc.number SUB_KERNEL_FUTEX_MUTEX_ALL_0100
47 * @tc.name basic test of pthread_mutex
48 * @tc.desc [C- SOFTWARE -0200]
49 */
50 HWTEST_F(FutexTest, testPthreadMutex, Function | MediumTest | Level3)
51 {
52 pthread_mutex_t mtx;
53 const int loopNum = 5;
54 pthread_t tid[loopNum];
55
56 EXPECT_EQ(pthread_mutex_init(&mtx, nullptr), 0) << "> return errno";
57
58 for (int i = 0; i < loopNum; i++) {
59 EXPECT_EQ(pthread_create(&tid[i], nullptr, ThreadMutex, (void*)&mtx), 0) << "> return errno";
60 }
61 for (int i = 0; i < loopNum; i++) {
62 EXPECT_EQ(pthread_join(tid[i], nullptr), 0) << "> return errno";
63 }
64 EXPECT_EQ(pthread_mutex_destroy(&mtx), 0) << "> return errno";
65 }
66
67 /********************************************* Test case dividing line ***********************************************/
68
ThreadMtrylock1(void * arg)69 void *ThreadMtrylock1(void *arg)
70 {
71 pthread_mutex_t *mtx = (pthread_mutex_t *)arg;
72 EXPECT_EQ(pthread_mutex_trylock(mtx), 0) << "> return errno";
73 CheckStep(1);
74 Msleep(50);
75 CheckStep(4);
76 EXPECT_EQ(pthread_mutex_unlock(mtx), 0) << "> return errno";
77 CheckStep(5);
78 return arg;
79 }
80
ThreadMtrylock2(void * arg)81 void *ThreadMtrylock2(void *arg)
82 {
83 Msleep(20);
84 pthread_mutex_t *mtx = (pthread_mutex_t *)arg;
85 CheckStep(2);
86 EXPECT_EQ(pthread_mutex_trylock(mtx), EBUSY) << "> should return errno";
87 CheckStep(3);
88 return arg;
89 }
90
91 /**
92 * @tc.number SUB_KERNEL_FUTEX_MUTEX_ALL_0200
93 * @tc.name basic test of pthread_mutex_trylock
94 * @tc.desc [C- SOFTWARE -0200]
95 */
96 HWTEST_F(FutexTest, testPthreadMtrylock, Function | MediumTest | Level3)
97 {
98 pthread_t tid[2];
99 pthread_mutex_t mtx;
100
101 EXPECT_EQ(pthread_mutex_init(&mtx, nullptr), 0) << "> return errno";
102 EXPECT_EQ(pthread_create(&tid[0], nullptr, ThreadMtrylock1, (void*)&mtx), 0) << "> return errno";
103 EXPECT_EQ(pthread_create(&tid[1], nullptr, ThreadMtrylock2, (void*)&mtx), 0) << "> return errno";
104
105 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
106 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
107
108 EXPECT_EQ(pthread_mutex_destroy(&mtx), 0) << "> return errno";
109 EXPECT_EQ(CheckStep(6), (uint64_t)0x123456);
110 }
111
112 /********************************************* Test case dividing line ***********************************************/
113
114 struct PthreadMutexCond {
115 const int loopNum = 10;
116 const int countMax = 5;
117 int count = 0;
118 int top = 0;
119 int bottom = 0;
120 pthread_cond_t notfull = PTHREAD_COND_INITIALIZER;
121 pthread_cond_t notempty = PTHREAD_COND_INITIALIZER;
122 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
123 } g_st1;
124
PthreadProduce(void * arg)125 void *PthreadProduce(void *arg)
126 {
127 for (int i = 0; i < g_st1.loopNum; i++) {
128 EXPECT_EQ(pthread_mutex_lock(&g_st1.mutex), 0) << "> return errno";
129 // check full
130 if ((g_st1.top + 1) % g_st1.countMax == g_st1.bottom) {
131 EXPECT_EQ(pthread_cond_wait(&g_st1.notempty, &g_st1.mutex), 0);
132 }
133 // Produce
134 g_st1.top = (g_st1.top + 1) % g_st1.countMax;
135 g_st1.count++;
136 LOG("producer g_st1.top = %d", g_st1.top);
137
138 EXPECT_EQ(pthread_cond_signal(&g_st1.notempty), 0);
139 EXPECT_EQ(pthread_mutex_unlock(&g_st1.mutex), 0) << "> return errno";
140 Msleep(10);
141 }
142 return arg;
143 }
144
PthreadConsume(void * arg)145 void *PthreadConsume(void *arg)
146 {
147 for (int i = 0; i < g_st1.loopNum; i++) {
148 EXPECT_EQ(pthread_mutex_lock(&g_st1.mutex), 0) << "> return errno";
149 // check empty
150 if (g_st1.top == g_st1.bottom) {
151 EXPECT_EQ(pthread_cond_wait(&g_st1.notempty, &g_st1.mutex), 0);
152 }
153 // Consume
154 g_st1.bottom = (g_st1.bottom + 1) % g_st1.countMax;
155 g_st1.count--;
156 LOG("consume g_st1.bottom = %d", g_st1.bottom);
157
158 EXPECT_EQ(pthread_cond_signal(&g_st1.notempty), 0);
159 EXPECT_EQ(pthread_mutex_unlock(&g_st1.mutex), 0) << "> return errno";
160
161 Msleep(10);
162 }
163 return arg;
164 }
165
166 /**
167 * @tc.number SUB_KERNEL_FUTEX_MUTEX_ALL_0300
168 * @tc.name test pthread_mutex with condition variable, produce and consume
169 * @tc.desc [C- SOFTWARE -0200]
170 */
171 HWTEST_F(FutexTest, testPthreadMutexCond, Function | MediumTest | Level3)
172 {
173 pthread_t tid[2];
174 g_st1.count = 0;
175 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadProduce, nullptr), 0) << "> return errno";
176 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadConsume, nullptr), 0) << "> return errno";
177 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
178 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
179 EXPECT_EQ(g_st1.count, 0);
180 }
181
182 /********************************************* Test case dividing line ***********************************************/
183
ThreadPthreadMtimedlockOut(void * arg)184 void *ThreadPthreadMtimedlockOut(void *arg)
185 {
186 pthread_mutex_t *mtx = (pthread_mutex_t*)arg;
187 struct timespec ts = {0};
188 struct timespec tsNow = {0};
189
190 Msleep(20);
191 CheckStep(1);
192 GetDelayedTime(&ts, 100);
193 EXPECT_EQ(pthread_mutex_timedlock(mtx, &ts), ETIMEDOUT) << "> return should errno";
194
195 CheckStep(3);
196 clock_gettime(CLOCK_REALTIME, &tsNow);
197 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
198 EXPECT_GE(timeDiff, 0);
199 EXPECT_LE(timeDiff, 20);
200 return arg;
201 }
202
203 /**
204 * @tc.number SUB_KERNEL_FUTEX_PTHREAD_TIMEDLOCK_0100
205 * @tc.name test pthread_mutex_timedlock whith timeout
206 * @tc.desc [C- SOFTWARE -0200]
207 */
208 HWTEST_F(FutexTest, testPthreadMtimedlockOut, Function | MediumTest | Level3)
209 {
210 pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
211 pthread_t tid;
212 EXPECT_EQ(pthread_create(&tid, nullptr, ThreadPthreadMtimedlockOut, (void*)&mtx), 0) << "> return errno";
213
214 EXPECT_EQ(pthread_mutex_lock(&mtx), 0) << "> return errno";
215 Msleep(50);
216 CheckStep(2);
217 Msleep(100);
218 CheckStep(4);
219 EXPECT_EQ(pthread_mutex_unlock(&mtx), 0) << "> return errno";
220
221 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno";
222 EXPECT_EQ(CheckStep(5), (uint64_t)0x12345);
223 }
224
225 /********************************************* Test case dividing line ***********************************************/
226
ThreadPthreadMtimedlockNoOut(void * arg)227 void *ThreadPthreadMtimedlockNoOut(void *arg)
228 {
229 pthread_mutex_t *mtx = (pthread_mutex_t*)arg;
230 struct timespec ts = {0};
231
232 Msleep(20);
233 CheckStep(1);
234 GetDelayedTime(&ts, 100);
235 EXPECT_EQ(pthread_mutex_timedlock(mtx, &ts), 0) << "> return errno";
236 CheckStep(3);
237 return arg;
238 }
239
240 /**
241 * @tc.number SUB_KERNEL_FUTEX_PTHREAD_TIMEDLOCK_0200
242 * @tc.name test pthread_mutex_timedlock with no timeout
243 * @tc.desc [C- SOFTWARE -0200]
244 */
245 HWTEST_F(FutexTest, testPthreadMtimedlockNoOut, Function | MediumTest | Level3)
246 {
247 pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
248 pthread_t tid;
249 EXPECT_EQ(pthread_create(&tid, nullptr, ThreadPthreadMtimedlockNoOut, (void*)&mtx), 0) << "> return errno";
250
251 EXPECT_EQ(pthread_mutex_lock(&mtx), 0) << "> return errno";
252 Msleep(50);
253 CheckStep(2);
254 EXPECT_EQ(pthread_mutex_unlock(&mtx), 0) << "> return errno";
255
256 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno";
257 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234);
258 }
259
260 /********************************************* Test case dividing line ***********************************************/
261
262 /**
263 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0100
264 * @tc.name test pthread_mutexattr_init api
265 * @tc.desc [C- SOFTWARE -0200]
266 */
267 HWTEST_F(FutexTest, testPthreadMattrType, Function | MediumTest | Level1)
268 {
269 int type;
270 pthread_mutexattr_t mutexTypeAttr;
271 int errorType = 100;
272
273 EXPECT_EQ(pthread_mutexattr_init(&mutexTypeAttr), 0);
274
275 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_DEFAULT), 0) << "> return errno";
276 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0);
277 EXPECT_EQ(type, PTHREAD_MUTEX_DEFAULT);
278
279 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_NORMAL), 0) << "> return errno";
280 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0);
281 EXPECT_EQ(type, PTHREAD_MUTEX_NORMAL);
282
283 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_RECURSIVE), 0) << "> return errno";
284 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0);
285 EXPECT_EQ(type, PTHREAD_MUTEX_RECURSIVE);
286
287 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_ERRORCHECK), 0) << "> return errno";
288 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0);
289 EXPECT_EQ(type, PTHREAD_MUTEX_ERRORCHECK);
290
291 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, errorType), EINVAL) << "> return errno";
292 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0);
293 EXPECT_NE(type, errorType);
294 }
295
296 /********************************************* Test case dividing line ***********************************************/
297
ThreadMattrTypeRecursive1(void * arg)298 void *ThreadMattrTypeRecursive1(void *arg)
299 {
300 pthread_mutex_t *mtx = (pthread_mutex_t *)arg;
301 ChildAssertEQ(pthread_mutex_lock(mtx), 0);
302 Msleep(30);
303 ChildAssertEQ(pthread_mutex_unlock(mtx), 0);
304 return arg;
305 }
306
307 /**
308 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0200
309 * @tc.name type is PTHREAD_MUTEX_RECURSIVE, unlock when not in use
310 * @tc.desc [C- SOFTWARE -0200]
311 */
312 HWTEST_F(FutexTest, testPthreadMattrTypeRecursive1, Function | MediumTest | Level2)
313 {
314 pid_t pid = fork();
315 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
316 if (pid == 0) {
317 int exitCode = 0;
318 int type;
319 pthread_t tid;
320 pthread_mutex_t mtx;
321 pthread_mutexattr_t mtxTypeAttr;
322
323 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0);
324 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_RECURSIVE), 0);
325 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0);
326 ChildAssertEQ(type, PTHREAD_MUTEX_RECURSIVE);
327 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0);
328 ChildAssertEQ(pthread_create(&tid, nullptr, ThreadMattrTypeRecursive1, (void*)&mtx), 0);
329 Msleep(10);
330 exitCode = ChildExpectEQ(pthread_mutex_unlock(&mtx), EPERM);
331 ChildAssertEQ(pthread_join(tid, nullptr), 0);
332 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0);
333 exit(exitCode);
334 }
335 Msleep(80);
336 WaitProcExitedOK(pid);
337 }
338
339 /********************************************* Test case dividing line ***********************************************/
340
341 /**
342 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0300
343 * @tc.name type is PTHREAD_MUTEX_RECURSIVE, lock when locked
344 * @tc.desc [C- SOFTWARE -0200]
345 */
346 HWTEST_F(FutexTest, testPthreadMattrTypeRecursive2, Function | MediumTest | Level2)
347 {
348 pid_t pid = fork();
349 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
350 if (pid == 0) {
351 int exitCode = 0;
352 int type;
353 pthread_mutex_t mtx;
354 pthread_mutexattr_t mtxTypeAttr;
355
356 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0);
357 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_RECURSIVE), 0);
358 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0);
359 ChildAssertEQ(type, PTHREAD_MUTEX_RECURSIVE);
360 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0);
361
362 ChildAssertEQ(pthread_mutex_lock(&mtx), 0);
363 exitCode = ChildExpectEQ(pthread_mutex_lock(&mtx), 0);
364 ChildAssertEQ(pthread_mutex_unlock(&mtx), 0);
365
366 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0);
367 exit(exitCode);
368 }
369 Msleep(50);
370 AssertProcExitedOK(pid);
371 }
372
373 /********************************************* Test case dividing line ***********************************************/
374
ThreadMattrTypeRecursive3(void * arg)375 void *ThreadMattrTypeRecursive3(void *arg)
376 {
377 pthread_mutex_t *mtx = (pthread_mutex_t *)arg;
378 ChildAssertEQ(pthread_mutex_lock(mtx), 0);
379 Msleep(30);
380 ChildAssertEQ(pthread_mutex_unlock(mtx), 0);
381 return arg;
382 }
383
384 /**
385 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0400
386 * @tc.name type is PTHREAD_MUTEX_ERRORCHECK, unlock when not in use
387 * @tc.desc [C- SOFTWARE -0200]
388 */
389 HWTEST_F(FutexTest, testPthreadMattrTypeRecursive3, Function | MediumTest | Level2)
390 {
391 pid_t pid = fork();
392 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
393 if (pid == 0) {
394 int exitCode;
395 int type;
396 pthread_t tid;
397 pthread_mutex_t mtx;
398 pthread_mutexattr_t mtxTypeAttr;
399
400 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0);
401 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_ERRORCHECK), 0);
402 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0);
403 ChildAssertEQ(type, PTHREAD_MUTEX_ERRORCHECK);
404 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0);
405 ChildAssertEQ(pthread_create(&tid, nullptr, ThreadMattrTypeRecursive3, (void*)&mtx), 0);
406 Msleep(10);
407 exitCode = ChildExpectEQ(pthread_mutex_unlock(&mtx), EPERM);
408 ChildAssertEQ(pthread_join(tid, nullptr), 0);
409 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0);
410 exit(exitCode);
411 }
412 Msleep(80);
413 WaitProcExitedOK(pid);
414 }
415
416 /********************************************* Test case dividing line ***********************************************/
417
418 /**
419 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0500
420 * @tc.name type is PTHREAD_MUTEX_ERRORCHECK, lock when locked
421 * @tc.desc [C- SOFTWARE -0200]
422 */
423 HWTEST_F(FutexTest, testPthreadMattrTypeRecursive4, Function | MediumTest | Level2)
424 {
425 pid_t pid = fork();
426 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
427 if (pid == 0) {
428 int exitCode = 0;
429 int type;
430 pthread_mutex_t mtx;
431 pthread_mutexattr_t mtxTypeAttr;
432
433 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0);
434 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_ERRORCHECK), 0);
435 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0);
436 ChildAssertEQ(type, PTHREAD_MUTEX_ERRORCHECK);
437 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0);
438
439 ChildAssertEQ(pthread_mutex_lock(&mtx), 0);
440 exitCode = ChildExpectEQ(pthread_mutex_lock(&mtx), EDEADLK);
441 ChildAssertEQ(pthread_mutex_unlock(&mtx), 0);
442
443 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0);
444 exit(exitCode);
445 }
446 Msleep(50);
447 AssertProcExitedOK(pid);
448 }
449
450 /********************************************* Test case dividing line ***********************************************/
451
452 /**
453 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0600
454 * @tc.name type is PTHREAD_MUTEX_NORMAL, lock when locked
455 * @tc.desc [C- SOFTWARE -0200]
456 */
457 HWTEST_F(FutexTest, testPthreadMattrTypeRecursive5, Function | MediumTest | Level2)
458 {
459 pid_t pid = fork();
460 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
461 if (pid == 0) {
462 int type;
463 pthread_mutex_t mtx;
464 pthread_mutexattr_t mtxTypeAttr;
465
466 LOG("> child pid = %d", getpid());
467 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0);
468 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_NORMAL), 0);
469 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0);
470 ChildAssertEQ(type, PTHREAD_MUTEX_NORMAL);
471 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0);
472 LOG("> lock");
473 ChildAssertEQ(pthread_mutex_lock(&mtx), 0);
474
475 // if add pthread_mutex_lock Unreachable
476 LOG("> unlock");
477 ChildAssertEQ(pthread_mutex_unlock(&mtx), 0);
478 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0);
479 exit(0);
480 }
481 LOG("> parent pid = %d", getpid());
482 Msleep(50);
483 WaitProcExitedOK(pid);
484 }
485
486 /********************************************* Test case dividing line ***********************************************/
487
ThreadSpinlock(void * arg)488 void *ThreadSpinlock(void *arg)
489 {
490 pthread_spinlock_t *spinLock = (pthread_spinlock_t *)arg;
491 EXPECT_EQ(pthread_spin_lock(spinLock), 0) << "> return errno";
492 CheckStep(1);
493 Msleep(10);
494 EXPECT_EQ(CheckStep(2), (uint64_t)0x12);
495 EXPECT_EQ(pthread_spin_unlock(spinLock), 0) << "> return errno";
496 return arg;
497 }
498
499 /**
500 * @tc.number SUB_KERNEL_FUTEX_SPINLOCK_ALL_0100
501 * @tc.name basic test of pthread_spin_lock
502 * @tc.desc [C- SOFTWARE -0200]
503 */
504 HWTEST_F(FutexTest, testPthreadSpinlock, Function | MediumTest | Level3)
505 {
506 pthread_spinlock_t spinLock;
507 const int loopNum = 5;
508 pthread_t tid[loopNum];
509
510 EXPECT_EQ(pthread_spin_init(&spinLock, 0), 0);
511
512 for (int i = 0; i < loopNum; i++) {
513 EXPECT_EQ(pthread_create(&tid[i], nullptr, ThreadSpinlock, (void*)&spinLock), 0) << "> return errno";
514 }
515 for (int i = 0; i < loopNum; i++) {
516 EXPECT_EQ(pthread_join(tid[i], nullptr), 0) << "> return errno";
517 }
518 EXPECT_EQ(pthread_spin_destroy(&spinLock), 0);
519 }
520
521 /********************************************* Test case dividing line ***********************************************/
522
ThreadSpinTrylock1(void * arg)523 void *ThreadSpinTrylock1(void *arg)
524 {
525 pthread_spinlock_t *spinLock = (pthread_spinlock_t *)arg;
526 EXPECT_EQ(pthread_spin_trylock(spinLock), 0) << "> return errno";
527 CheckStep(1);
528 Msleep(50);
529 CheckStep(4);
530 EXPECT_EQ(pthread_spin_unlock(spinLock), 0) << "> return errno";
531 CheckStep(5);
532 return arg;
533 }
534
ThreadSpinTrylock2(void * arg)535 void *ThreadSpinTrylock2(void *arg)
536 {
537 Msleep(20);
538 pthread_spinlock_t *spinLock = (pthread_spinlock_t *)arg;
539 CheckStep(2);
540 EXPECT_EQ(pthread_spin_trylock(spinLock), EBUSY) << "> should return errno";
541 CheckStep(3);
542 return arg;
543 }
544
545 /**
546 * @tc.number SUB_KERNEL_FUTEX_SPINLOCK_ALL_0200
547 * @tc.name basic test of pthread_spin_trylock
548 * @tc.desc [C- SOFTWARE -0200]
549 */
550 HWTEST_F(FutexTest, testPthreadSpinTrylock, Function | MediumTest | Level3)
551 {
552 pthread_t tid[2];
553 pthread_spinlock_t spinLock;
554
555 EXPECT_EQ(pthread_spin_init(&spinLock, 0), 0) << "> return errno";
556 EXPECT_EQ(pthread_create(&tid[0], nullptr, ThreadSpinTrylock1, (void*)&spinLock), 0) << "> return errno";
557 EXPECT_EQ(pthread_create(&tid[1], nullptr, ThreadSpinTrylock2, (void*)&spinLock), 0) << "> return errno";
558
559 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno";
560 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno";
561
562 EXPECT_EQ(pthread_spin_destroy(&spinLock), 0);
563 EXPECT_EQ(pthread_spin_trylock(&spinLock), 0) << "> return errno";
564 EXPECT_EQ(CheckStep(6), (uint64_t)0x123456);
565 }
566