1/*
2 * Copyright (C) 2022 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 <stdlib.h>
17#include <threads.h>
18#include <unistd.h>
19#include "functionalext.h"
20
21static mtx_t g_mtex;
22
23int threadfuncA(void *arg)
24{
25    int32_t ret = 0;
26    ret = mtx_lock(&g_mtex);
27    EXPECT_EQ("mtx_lock_0100", ret, thrd_success);
28    ret = mtx_unlock(&g_mtex);
29    EXPECT_EQ("mtx_lock_0100", ret, thrd_success);
30    return 0;
31}
32
33int threadfuncB(void *arg)
34{
35    int32_t ret = 0;
36    ret = mtx_lock(&g_mtex);
37    EXPECT_EQ("mtx_lock_0200", ret, thrd_success);
38    ret = mtx_unlock(&g_mtex);
39    EXPECT_EQ("mtx_lock_0200", ret, thrd_success);
40    return 0;
41}
42
43int threadfuncC(void *arg)
44{
45    int32_t ret = 0;
46    ret = mtx_lock(&g_mtex);
47    EXPECT_EQ("mtx_lock_0300", ret, thrd_success);
48    ret = mtx_unlock(&g_mtex);
49    EXPECT_EQ("mtx_lock_0300", ret, thrd_success);
50    return 0;
51}
52
53int threadfuncD(void *arg)
54{
55    int32_t ret = 0;
56    ret = mtx_lock(&g_mtex);
57    EXPECT_EQ("mtx_lock_0400", ret, thrd_success);
58    ret = mtx_unlock(&g_mtex);
59    EXPECT_EQ("mtx_lock_0400", ret, thrd_success);
60    return 0;
61}
62
63int threadfuncE(void *arg)
64{
65    int32_t ret = 0;
66    ret = mtx_lock(&g_mtex);
67    ret = mtx_lock(&g_mtex);
68    EXPECT_EQ("mtx_lock_0500", ret, thrd_success);
69    ret = mtx_unlock(&g_mtex);
70    EXPECT_EQ("mtx_lock_0500", ret, thrd_success);
71    return 0;
72}
73
74/**
75 * @tc.name      : mtx_lock_0100
76 * @tc.desc      : Verify process mtx_lock success when mtx_init second args is mtx_plain.
77 * @tc.level     : Level 0
78 */
79void mtx_lock_0100(void)
80{
81    int result = mtx_init(&g_mtex, mtx_plain);
82    if (result != thrd_success) {
83        t_error("%s mtx_init failed", __func__);
84        return;
85    }
86    thrd_t tid1;
87    thrd_create(&tid1, threadfuncA, NULL);
88    if (result != thrd_success) {
89        t_error("%s thrd_create failed", __func__);
90        return;
91    }
92    thrd_join(tid1, NULL);
93    if (result != thrd_success) {
94        t_error("%s thrd_join failed", __func__);
95        return;
96    }
97}
98
99/**
100 * @tc.name      : mtx_lock_0200
101 * @tc.desc      : Verify process mtx_lock success when mtx_init second args is mtx_timed.
102 * @tc.level     : Level 0
103 */
104void mtx_lock_0200(void)
105{
106    int result = mtx_init(&g_mtex, mtx_timed);
107    if (result != thrd_success) {
108        t_error("%s mtx_init failed", __func__);
109        return;
110    }
111    thrd_t tid2;
112    thrd_create(&tid2, threadfuncB, NULL);
113    if (result != thrd_success) {
114        t_error("%s thrd_create failed", __func__);
115        return;
116    }
117    thrd_join(tid2, NULL);
118    if (result != thrd_success) {
119        t_error("%s thrd_join failed", __func__);
120        return;
121    }
122}
123
124/**
125 * @tc.name      : mtx_lock_0300
126 * @tc.desc      : Verify process mtx_lock success when mtx_plain second args is mtx_plain | mtx_recursive.
127 * @tc.level     : Level 0
128 */
129void mtx_lock_0300(void)
130{
131    int result = mtx_init(&g_mtex, mtx_plain | mtx_recursive);
132    if (result != thrd_success) {
133        t_error("%s mtx_init failed", __func__);
134        return;
135    }
136    thrd_t tid3;
137    thrd_create(&tid3, threadfuncC, NULL);
138    if (result != thrd_success) {
139        t_error("%s thrd_create failed", __func__);
140        return;
141    }
142    thrd_join(tid3, NULL);
143    if (result != thrd_success) {
144        t_error("%s thrd_join failed", __func__);
145        return;
146    }
147}
148
149/**
150 * @tc.name      : mtx_lock_0400
151 * @tc.desc      : Verify process mtx_lock success when mtx_plain second args is mtx_timed | mtx_recursive.
152 * @tc.level     : Level 0
153 */
154void mtx_lock_0400(void)
155{
156    int result= mtx_init(&g_mtex, mtx_timed | mtx_recursive);
157    if (result != thrd_success) {
158        t_error("%s mtx_init failed", __func__);
159        return;
160    }
161    thrd_t tid4;
162    thrd_create(&tid4, threadfuncD, NULL);
163    if (result != thrd_success) {
164        t_error("%s thrd_create failed", __func__);
165        return;
166    }
167    thrd_join(tid4, NULL);
168    if (result != thrd_success) {
169        t_error("%s thrd_join failed", __func__);
170        return;
171    }
172}
173
174
175/**
176 * @tc.name      : mtx_lock_0500
177 * @tc.desc      : Verify process mtx_lock twice success when mtx_plain second args is mtx_plain | mtx_recursive.
178 * @tc.level     : Level 1
179 */
180void mtx_lock_0500(void)
181{
182    int result = mtx_init(&g_mtex, mtx_plain | mtx_recursive);
183    if (result != thrd_success) {
184        t_error("%s mtx_init failed", __func__);
185        return;
186    }
187    thrd_t tid5;
188    thrd_create(&tid5, threadfuncE, NULL);
189    if (result != thrd_success) {
190        t_error("%s thrd_create failed", __func__);
191        return;
192    }
193    thrd_join(tid5, NULL);
194    if (result != thrd_success) {
195        t_error("%s thrd_join failed", __func__);
196        return;
197    }
198}
199
200int main(void)
201{
202    mtx_lock_0100();
203    mtx_lock_0200();
204    mtx_lock_0300();
205    mtx_lock_0400();
206    mtx_lock_0500();
207    return t_status;
208}