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 #include <errno.h>
16 #include <pthread.h>
17 #include "pthread_util.h"
18
19 /********************************************* Test case dividing line ***********************************************/
20
21 pthread_rwlock_t g_rwlock1;
22
PthreadClockRdlockNoOutRealTimeW1(void * arg)23 static void *PthreadClockRdlockNoOutRealTimeW1(void *arg)
24 {
25 TEST(pthread_rwlock_wrlock(&g_rwlock1) == 0);
26 Msleep(SLEEP_50_MS);
27 TEST(pthread_rwlock_unlock(&g_rwlock1) == 0);
28 return arg;
29 }
30
PthreadClockRdlockNoOutRealTimeR2(void * arg)31 static void *PthreadClockRdlockNoOutRealTimeR2(void *arg)
32 {
33 struct timespec ts = {0};
34 Msleep(SLEEP_20_MS);
35 GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_REALTIME);
36 TEST(pthread_rwlock_clockrdlock(&g_rwlock1, CLOCK_REALTIME, &ts) == 0);
37 TEST(pthread_rwlock_unlock(&g_rwlock1) == 0);
38 return arg;
39 }
40
41 /**
42 * @tc.name : pthread_rwlock_clockrdlock_0010
43 * @tc.desc : test pthread_rwlock_clockrdlock with no timeout by CLOCK_REALTIME , write - read
44 * @tc.level : Level 0
45 */
pthread_rwlock_clockrdlock_0010(void)46 static void pthread_rwlock_clockrdlock_0010(void)
47 {
48 pthread_t tid[2];
49 TEST(pthread_rwlock_init(&g_rwlock1, NULL) == 0);
50
51 TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockNoOutRealTimeW1, NULL) == 0);
52 TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockNoOutRealTimeR2, NULL) == 0);
53
54 TEST(pthread_join(tid[0], NULL) == 0);
55 TEST(pthread_join(tid[1], NULL) == 0);
56 TEST(pthread_rwlock_destroy(&g_rwlock1) == 0);
57 }
58
59 /********************************************* Test case dividing line ***********************************************/
60
61 pthread_rwlock_t g_rwlock2;
62
PthreadClockRdlockOutRealTimeW1(void * arg)63 static void *PthreadClockRdlockOutRealTimeW1(void *arg)
64 {
65 TEST(pthread_rwlock_wrlock(&g_rwlock2) == 0);
66 Msleep(SLEEP_50_MS);
67 Msleep(SLEEP_100_MS);
68 TEST(pthread_rwlock_unlock(&g_rwlock2) == 0);
69 return arg;
70 }
71
PthreadClockRdlockOutRealTimeR2(void * arg)72 static void *PthreadClockRdlockOutRealTimeR2(void *arg)
73 {
74 struct timespec ts = {0};
75 struct timespec tsNow = {0};
76 Msleep(SLEEP_20_MS);
77 GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_REALTIME);
78 TEST(pthread_rwlock_clockrdlock(&g_rwlock2, CLOCK_REALTIME, &ts) == ETIMEDOUT);
79 clock_gettime(CLOCK_REALTIME, &tsNow);
80 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
81 TEST(timeDiff < 20);
82 return arg;
83 }
84
85 /**
86 * @tc.name : pthread_rwlock_clockrdlock_0020
87 * @tc.desc : test pthread_rwlock_clockrdlock with timeout by CLOCK_REALTIME, write - read
88 * @tc.level : Level 0
89 */
pthread_rwlock_clockrdlock_0020(void)90 static void pthread_rwlock_clockrdlock_0020(void)
91 {
92 pthread_t tid[2];
93 TEST(pthread_rwlock_init(&g_rwlock2, NULL) == 0);
94
95 TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockOutRealTimeW1, NULL) == 0);
96 TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockOutRealTimeR2, NULL) == 0);
97
98 TEST(pthread_join(tid[0], NULL) == 0);
99 TEST(pthread_join(tid[1], NULL) == 0);
100 TEST(pthread_rwlock_destroy(&g_rwlock2) == 0);
101 }
102
103
104 /********************************************* Test case dividing line ***********************************************/
105
106 pthread_rwlock_t g_rwlock3;
107
PthreadClockRdlockNoOutMonoTimeW1(void * arg)108 static void *PthreadClockRdlockNoOutMonoTimeW1(void *arg)
109 {
110 TEST(pthread_rwlock_wrlock(&g_rwlock3) == 0);
111 Msleep(SLEEP_50_MS);
112 TEST(pthread_rwlock_unlock(&g_rwlock3) == 0);
113 return arg;
114 }
115
PthreadClockRdlockNoOutMonoTimeR2(void * arg)116 static void *PthreadClockRdlockNoOutMonoTimeR2(void *arg)
117 {
118 struct timespec ts = {0};
119 Msleep(SLEEP_20_MS);
120 GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
121 TEST(pthread_rwlock_clockrdlock(&g_rwlock3, CLOCK_MONOTONIC, &ts) == 0);
122 TEST(pthread_rwlock_unlock(&g_rwlock3) == 0);
123 return arg;
124 }
125
126 /**
127 * @tc.name : pthread_rwlock_clockrdlock_0030
128 * @tc.desc : test pthread_rwlock_clockrdlock with no timeout by CLOCK_MONOTONIC , write - read
129 * @tc.level : Level 0
130 */
pthread_rwlock_clockrdlock_0030(void)131 static void pthread_rwlock_clockrdlock_0030(void)
132 {
133 pthread_t tid[2];
134 TEST(pthread_rwlock_init(&g_rwlock3, NULL) == 0);
135
136 TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockNoOutMonoTimeW1, NULL) == 0);
137 TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockNoOutMonoTimeR2, NULL) == 0);
138
139 TEST(pthread_join(tid[0], NULL) == 0);
140 TEST(pthread_join(tid[1], NULL) == 0);
141 TEST(pthread_rwlock_destroy(&g_rwlock3) == 0);
142 }
143
144 /********************************************* Test case dividing line ***********************************************/
145
146 pthread_rwlock_t g_rwlock4;
147
PthreadClockRdlockOutMonoTimeW1(void * arg)148 static void *PthreadClockRdlockOutMonoTimeW1(void *arg)
149 {
150 TEST(pthread_rwlock_wrlock(&g_rwlock4) == 0);
151 Msleep(SLEEP_50_MS);
152 Msleep(SLEEP_100_MS);
153 TEST(pthread_rwlock_unlock(&g_rwlock4) == 0);
154 return arg;
155 }
156
PthreadClockRdlockOutMonoTimeR2(void * arg)157 static void *PthreadClockRdlockOutMonoTimeR2(void *arg)
158 {
159 struct timespec ts = {0};
160 struct timespec tsNow = {0};
161 Msleep(SLEEP_20_MS);
162 GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
163 TEST(pthread_rwlock_clockrdlock(&g_rwlock4, CLOCK_MONOTONIC, &ts) == ETIMEDOUT);
164 clock_gettime(CLOCK_MONOTONIC, &tsNow);
165 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
166 TEST(timeDiff < 20);
167 return arg;
168 }
169
170 /**
171 * @tc.name : pthread_rwlock_clockrdlock_0040
172 * @tc.desc : test pthread_rwlock_clockrdlock with timeout by CLOCK_MONOTONIC, write - read
173 * @tc.level : Level 0
174 */
pthread_rwlock_clockrdlock_0040(void)175 static void pthread_rwlock_clockrdlock_0040(void)
176 {
177 pthread_t tid[2];
178 TEST(pthread_rwlock_init(&g_rwlock4, NULL) == 0);
179
180 TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockOutMonoTimeW1, NULL) == 0);
181 TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockOutMonoTimeR2, NULL) == 0);
182
183 TEST(pthread_join(tid[0], NULL) == 0);
184 TEST(pthread_join(tid[1], NULL) == 0);
185 TEST(pthread_rwlock_destroy(&g_rwlock4) == 0);
186 }
187
188 /********************************************* Test case dividing line ***********************************************/
189
190 pthread_rwlock_t g_rwlock5;
191
PthreadTimedRdlockMonoNPNoOutW1(void * arg)192 static void *PthreadTimedRdlockMonoNPNoOutW1(void *arg)
193 {
194 TEST(pthread_rwlock_wrlock(&g_rwlock5) == 0);
195 Msleep(SLEEP_50_MS);
196 TEST(pthread_rwlock_unlock(&g_rwlock5) == 0);
197 return arg;
198 }
199
PthreadTimedRdlockMonoNPNoOutR2(void * arg)200 static void *PthreadTimedRdlockMonoNPNoOutR2(void *arg)
201 {
202 struct timespec ts = {0};
203 Msleep(SLEEP_20_MS);
204 GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
205 TEST(pthread_rwlock_timedrdlock_monotonic_np(&g_rwlock5, &ts) == 0);
206 TEST(pthread_rwlock_unlock(&g_rwlock5) == 0);
207 return arg;
208 }
209
210 /**
211 * @tc.name : pthread_rwlock_timedrdlock_monotonic_np_0010
212 * @tc.desc : test pthread_rwlock_timedrdlock_monotonic_np with no timeout by CLOCK_MONOTONIC, write - read
213 * @tc.level : Level 0
214 */
pthread_rwlock_timedrdlock_monotonic_np_0010(void)215 static void pthread_rwlock_timedrdlock_monotonic_np_0010(void)
216 {
217 pthread_t tid[2];
218 TEST(pthread_rwlock_init(&g_rwlock5, NULL) == 0);
219
220 TEST(pthread_create(&tid[0], NULL, PthreadTimedRdlockMonoNPNoOutW1, NULL) == 0);
221 TEST(pthread_create(&tid[1], NULL, PthreadTimedRdlockMonoNPNoOutR2, NULL) == 0);
222
223 TEST(pthread_join(tid[0], NULL) == 0);
224 TEST(pthread_join(tid[1], NULL) == 0);
225 TEST(pthread_rwlock_destroy(&g_rwlock5) == 0);
226 }
227
228 /********************************************* Test case dividing line ***********************************************/
229
230 pthread_rwlock_t g_rwlock6;
231
PthreadTimedRdlockMonoNPOutW1(void * arg)232 static void *PthreadTimedRdlockMonoNPOutW1(void *arg)
233 {
234 TEST(pthread_rwlock_wrlock(&g_rwlock6) == 0);
235 Msleep(SLEEP_50_MS);
236 Msleep(SLEEP_100_MS);
237 TEST(pthread_rwlock_unlock(&g_rwlock6) == 0);
238 return arg;
239 }
240
PthreadTimedRdlockMonoNPOutR2(void * arg)241 static void *PthreadTimedRdlockMonoNPOutR2(void *arg)
242 {
243 struct timespec ts = {0};
244 struct timespec tsNow = {0};
245 Msleep(SLEEP_20_MS);
246 GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
247 TEST(pthread_rwlock_timedrdlock_monotonic_np(&g_rwlock6, &ts) == ETIMEDOUT);
248 clock_gettime(CLOCK_MONOTONIC, &tsNow);
249 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
250 TEST(timeDiff < 20);
251 return arg;
252 }
253
254 /**
255 * @tc.name : pthread_rwlock_timedrdlock_monotonic_np_0020
256 * @tc.desc : test pthread_rwlock_timedrdlock_monotonic_np with timeout by CLOCK_MONOTONIC, write - read
257 * @tc.level : Level 0
258 */
pthread_rwlock_timedrdlock_monotonic_np_0020(void)259 static void pthread_rwlock_timedrdlock_monotonic_np_0020(void)
260 {
261 pthread_t tid[2];
262 TEST(pthread_rwlock_init(&g_rwlock6, NULL) == 0);
263
264 TEST(pthread_create(&tid[0], NULL, PthreadTimedRdlockMonoNPOutW1, NULL) == 0);
265 TEST(pthread_create(&tid[1], NULL, PthreadTimedRdlockMonoNPOutR2, NULL) == 0);
266
267 TEST(pthread_join(tid[0], NULL) == 0);
268 TEST(pthread_join(tid[1], NULL) == 0);
269 TEST(pthread_rwlock_destroy(&g_rwlock6) == 0);
270 }
271
272 /**
273 * @tc.name : pthread_rwlock_timedrdlock_monotonic_np_0030
274 * @tc.desc : test pthread_rwlock_timedrdlock_monotonic_np with invalid rwlock
275 * @tc.level : Level 2
276 */
pthread_rwlock_timedrdlock_monotonic_np_0030(void)277 static void pthread_rwlock_timedrdlock_monotonic_np_0030(void)
278 {
279 struct timespec ts = {0};
280 EXPECT_EQ(pthread_rwlock_timedrdlock_monotonic_np((pthread_rwlock_t *)NULL, &ts), EINVAL);
281 }
282
main(void)283 int main(void)
284 {
285 pthread_rwlock_clockrdlock_0010();
286 pthread_rwlock_clockrdlock_0020();
287 pthread_rwlock_clockrdlock_0030();
288 pthread_rwlock_clockrdlock_0040();
289 pthread_rwlock_timedrdlock_monotonic_np_0010();
290 pthread_rwlock_timedrdlock_monotonic_np_0020();
291 pthread_rwlock_timedrdlock_monotonic_np_0030();
292
293 return t_status;
294 }