• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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