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
29using namespace testing::ext;
30
31/********************************************* Test case dividing line ***********************************************/
32
33void *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 */
50HWTEST_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
69void *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
81void *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 */
96HWTEST_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
114struct 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
125void *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
145void *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 */
171HWTEST_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
184void *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 */
208HWTEST_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
227void *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 */
245HWTEST_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 */
267HWTEST_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
298void *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 */
312HWTEST_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 */
346HWTEST_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
375void *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 */
389HWTEST_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 */
423HWTEST_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 */
457HWTEST_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
488void *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 */
504HWTEST_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
523void *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
535void *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 */
550HWTEST_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