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