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 <sched.h>
18 #include "pthread_util.h"
19 
20 static pthread_rwlock_t w_rwlock1;
21 static pthread_rwlock_t w_rwlock2;
22 static pthread_rwlock_t w_rwlock3;
23 static pthread_rwlock_t w_rwlock4;
24 static pthread_rwlock_t w_rwlock5;
25 static pthread_rwlock_t w_rwlock6;
26 
RwlockClockRealTimeOut1(void *arg)27 static void *RwlockClockRealTimeOut1(void *arg)
28 {
29     EXPECT_EQ(pthread_rwlock_wrlock(&w_rwlock1), 0);
30     Msleep(SLEEP_50_MS);
31     Msleep(SLEEP_100_MS);
32     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock1), 0);
33     return arg;
34 }
35 
RwlockClockRealTimeOut2(void *arg)36 static void *RwlockClockRealTimeOut2(void *arg)
37 {
38     struct timespec ts = {0};
39     struct timespec tsNow = {0};
40     struct sched_param param;
41     param.sched_priority = sched_get_priority_max(SCHED_FIFO); // 获取最高优先级
42     if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &param) != 0) {
43         t_printf("pthread_setschedparam fail \n");
44         return arg;
45     }
46     Msleep(SLEEP_20_MS);
47     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, CLOCK_REALTIME);
48     EXPECT_EQ(pthread_rwlock_clockwrlock(&w_rwlock1, CLOCK_REALTIME, &ts), ETIMEDOUT);
49     clock_gettime(CLOCK_REALTIME, &tsNow);
50     int timeDiff = GetTimeDiff(tsNow, ts);
51     EXPECT_GE(timeDiff, 0);
52     EXPECT_LE(timeDiff, SLEEP_20_MS);
53     return arg;
54 }
55 
RwlockClockRealTimeWait1(void *arg)56 static void *RwlockClockRealTimeWait1(void *arg)
57 {
58     EXPECT_EQ(pthread_rwlock_wrlock(&w_rwlock2), 0);
59     Msleep(SLEEP_50_MS);
60     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock2), 0);
61     return arg;
62 }
63 
RwlockClockRealTimeWait2(void *arg)64 static void *RwlockClockRealTimeWait2(void *arg)
65 {
66     struct timespec ts = {0};
67     clockid_t clock_id = CLOCK_REALTIME;
68     Msleep(SLEEP_20_MS);
69     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, clock_id);
70     EXPECT_EQ(pthread_rwlock_clockwrlock(&w_rwlock2, clock_id, &ts), 0);
71     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock2), 0);
72     return arg;
73 }
74 
RwlockClockMonotonicTimeOut1(void *arg)75 static void *RwlockClockMonotonicTimeOut1(void *arg)
76 {
77     EXPECT_EQ(pthread_rwlock_wrlock(&w_rwlock5), 0);
78     Msleep(SLEEP_50_MS);
79     Msleep(SLEEP_100_MS);
80     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock5), 0);
81     return arg;
82 }
83 
RwlockClockMonotonicTimeOut2(void *arg)84 static void *RwlockClockMonotonicTimeOut2(void *arg)
85 {
86     struct timespec ts = {0};
87     struct timespec tsNow = {0};
88 
89     struct sched_param param;
90     param.sched_priority = sched_get_priority_max(SCHED_FIFO); // 获取最高优先级
91     if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &param) != 0) {
92         t_printf("pthread_setschedparam fail\n");
93         return arg;
94     }
95 
96     Msleep(SLEEP_20_MS);
97     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, CLOCK_MONOTONIC);
98     EXPECT_EQ(pthread_rwlock_clockwrlock(&w_rwlock5, CLOCK_MONOTONIC, &ts), ETIMEDOUT);
99     clock_gettime(CLOCK_MONOTONIC, &tsNow);
100     int timeDiff = GetTimeDiff(tsNow, ts);
101     EXPECT_GE(timeDiff, 0);
102     EXPECT_LE(timeDiff, SLEEP_20_MS);
103     return arg;
104 }
105 
RwlockClockMonotonicTimeWait1(void *arg)106 static void *RwlockClockMonotonicTimeWait1(void *arg)
107 {
108     EXPECT_EQ(pthread_rwlock_wrlock(&w_rwlock6), 0);
109     Msleep(SLEEP_50_MS);
110     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock6), 0);
111     return arg;
112 }
113 
RwlockClockMonotonicTimeWait2(void *arg)114 static void *RwlockClockMonotonicTimeWait2(void *arg)
115 {
116     struct timespec ts = {0};
117     Msleep(SLEEP_20_MS);
118     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, CLOCK_MONOTONIC);
119     EXPECT_EQ(pthread_rwlock_clockwrlock(&w_rwlock6, CLOCK_MONOTONIC, &ts), 0);
120     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock6), 0);
121     return arg;
122 }
123 
RwlockMonotonicTime1(void *arg)124 static void *RwlockMonotonicTime1(void *arg)
125 {
126     EXPECT_EQ(pthread_rwlock_wrlock(&w_rwlock3), 0);
127     Msleep(SLEEP_50_MS);
128     Msleep(SLEEP_100_MS);
129     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock3), 0);
130     return arg;
131 }
132 
RwlockMonotonicTime2(void *arg)133 static void *RwlockMonotonicTime2(void *arg)
134 {
135     struct timespec ts = {0};
136     struct timespec tsNow = {0};
137 
138     struct sched_param param;
139     param.sched_priority = sched_get_priority_max(SCHED_FIFO); // 获取最高优先级
140     if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &param) != 0) {
141         t_printf("pthread_setschedparam fail\n");
142         return arg;
143     }
144 
145     Msleep(SLEEP_20_MS);
146     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, CLOCK_MONOTONIC);
147     EXPECT_EQ(pthread_rwlock_timedwrlock_monotonic_np(&w_rwlock3, &ts), ETIMEDOUT);
148     clock_gettime(CLOCK_MONOTONIC, &tsNow);
149     int timeDiff = GetTimeDiff(tsNow, ts);
150     EXPECT_GE(timeDiff, 0);
151     EXPECT_LE(timeDiff, SLEEP_20_MS);
152     return arg;
153 }
154 
RwlockMonotonicTime3(void *arg)155 static void *RwlockMonotonicTime3(void *arg)
156 {
157     EXPECT_EQ(pthread_rwlock_wrlock(&w_rwlock4), 0);
158     Msleep(SLEEP_50_MS);
159     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock4), 0);
160     return arg;
161 }
162 
RwlockMonotonicTime4(void *arg)163 static void *RwlockMonotonicTime4(void *arg)
164 {
165     struct timespec ts = {0};
166     Msleep(SLEEP_20_MS);
167     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, CLOCK_MONOTONIC);
168     EXPECT_EQ(pthread_rwlock_timedwrlock_monotonic_np(&w_rwlock4, &ts), 0);
169     EXPECT_EQ(pthread_rwlock_unlock(&w_rwlock4), 0);
170     return arg;
171 }
172 
173 /**
174  * @tc.number    : pthread_rwlock_timedwrlock_0010
175  * @tc.desc      : Test whether all the interfaces to be used are normal
176  * @tc.level     : Level 0
177  */
178 
pthread_rwlock_timedwrlock_0010(void)179 void pthread_rwlock_timedwrlock_0010(void)
180 {
181     pthread_rwlock_t w;
182     struct timespec ts = {0};
183     EXPECT_EQ(clock_gettime(CLOCK_MONOTONIC, &ts), 0);
184     EXPECT_EQ(pthread_rwlock_init(&w, NULL), 0);
185     EXPECT_EQ(pthread_rwlock_wrlock(&w), 0);
186     EXPECT_EQ(pthread_rwlock_timedwrlock_monotonic_np(&w, &ts), ETIMEDOUT);
187     EXPECT_EQ(pthread_rwlock_unlock(&w), 0);
188     EXPECT_EQ(pthread_rwlock_destroy(&w), 0);
189 }
190 
191 /**
192  * @tc.number    : pthread_rwlock_timedwrlock_0020
193  * @tc.desc      : Test the case of pthread_cond_clockwait no timeout by CLOCK_REALTIME
194  * @tc.level     : Level 0
195  */
pthread_rwlock_timedwrlock_0020(void)196 void pthread_rwlock_timedwrlock_0020(void)
197 {
198     pthread_rwlock_t w;
199     struct timespec ts = {0};
200     clockid_t clock_id = CLOCK_REALTIME;
201     EXPECT_EQ(clock_gettime(CLOCK_REALTIME, &ts), 0);
202     EXPECT_EQ(pthread_rwlock_init(&w, NULL), 0);
203     EXPECT_EQ(pthread_rwlock_wrlock(&w), 0);
204     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, clock_id);
205     EXPECT_EQ(pthread_rwlock_clockwrlock(&w, clock_id, &ts), ETIMEDOUT);
206     EXPECT_EQ(pthread_rwlock_unlock(&w), 0);
207     EXPECT_EQ(pthread_rwlock_destroy(&w), 0);
208 }
209 
210 /**
211  * @tc.number    : pthread_rwlock_timedwrlock_0030
212  * @tc.desc      : Test the case of pthread_cond_clockwait no timeout by CLOCK_REALTIME
213  * @tc.level     : Level 0
214  */
pthread_rwlock_timedwrlock_0030(void)215 void pthread_rwlock_timedwrlock_0030(void)
216 {
217     pthread_rwlock_t w;
218     struct timespec ts = {0};
219     clockid_t clock_id = CLOCK_MONOTONIC;
220     EXPECT_EQ(clock_gettime(CLOCK_MONOTONIC, &ts), 0);
221     EXPECT_EQ(pthread_rwlock_init(&w, NULL), 0);
222     EXPECT_EQ(pthread_rwlock_wrlock(&w), 0);
223     GetDelayedTimeByClockid(&ts, SLEEP_100_MS, clock_id);
224     EXPECT_EQ(pthread_rwlock_clockwrlock(&w, clock_id, &ts), ETIMEDOUT);
225     EXPECT_EQ(pthread_rwlock_unlock(&w), 0);
226     EXPECT_EQ(pthread_rwlock_destroy(&w), 0);
227 }
228 
229 /**
230  * @tc.number    : pthread_rwlock_timedwrlock_0040
231  * @tc.desc      : Test the case of pthread_cond_clockwait no timeout by CLOCK_REALTIME
232  * @tc.level     : Level 2
233  */
pthread_rwlock_timedwrlock_0040(void)234 void pthread_rwlock_timedwrlock_0040(void)
235 {
236     pthread_rwlock_t w;
237     struct timespec ts = {0};
238     clockid_t clock_id = CLOCK_PROCESS_CPUTIME_ID;
239     EXPECT_EQ(pthread_rwlock_init(&w, NULL), 0);
240     EXPECT_EQ(pthread_rwlock_wrlock(&w), 0);
241     EXPECT_EQ(pthread_rwlock_clockwrlock(&w, clock_id, &ts), EINVAL);
242     EXPECT_EQ(pthread_rwlock_unlock(&w), 0);
243     EXPECT_EQ(pthread_rwlock_destroy(&w), 0);
244 }
245 
246 /**
247  * @tc.number    : pthread_rwlock_timedwrlock_0050
248  * @tc.desc      : Test the case of pthread_cond_clockwait no timeout by CLOCK_REALTIME
249  * @tc.level     : Level 1
250  */
pthread_rwlock_timedwrlock_0050(void)251 void pthread_rwlock_timedwrlock_0050(void)
252 {
253     pthread_t tid[2];
254     EXPECT_EQ(pthread_rwlock_init(&w_rwlock2, NULL), 0);
255 
256     EXPECT_EQ(pthread_create(&tid[0], NULL, RwlockClockRealTimeWait1, NULL), 0);
257     EXPECT_EQ(pthread_create(&tid[1], NULL, RwlockClockRealTimeWait2, NULL), 0);
258 
259     EXPECT_EQ(pthread_join(tid[0], NULL), 0);
260     EXPECT_EQ(pthread_join(tid[1], NULL), 0);
261     EXPECT_EQ(pthread_rwlock_destroy(&w_rwlock2), 0);
262 }
263 
264 /**
265  * @tc.number    : pthread_rwlock_timedwrlock_0060
266  * @tc.desc      : Test the case of pthread_cond_clockwait timeout by CLOCK_REALTIME
267  * @tc.level     : Level 1
268  */
pthread_rwlock_timedwrlock_0060(void)269 void pthread_rwlock_timedwrlock_0060(void)
270 {
271     pthread_t tid[2];
272     EXPECT_EQ(pthread_rwlock_init(&w_rwlock1, NULL), 0);
273 
274     EXPECT_EQ(pthread_create(&tid[0], NULL, RwlockClockRealTimeOut1, NULL), 0);
275     EXPECT_EQ(pthread_create(&tid[1], NULL, RwlockClockRealTimeOut2, NULL), 0);
276 
277     EXPECT_EQ(pthread_join(tid[0], NULL), 0);
278     EXPECT_EQ(pthread_join(tid[1], NULL), 0);
279     EXPECT_EQ(pthread_rwlock_destroy(&w_rwlock1), 0);
280 }
281 
282 /**
283  * @tc.number    : pthread_rwlock_timedwrlock_0070
284  * @tc.desc      : Test the case of pthread_cond_clockwait timeout by CLOCK_MONOTONIC
285  * @tc.level     : Level 1
286  */
pthread_rwlock_timedwrlock_0070(void)287 void pthread_rwlock_timedwrlock_0070(void)
288 {
289     pthread_t tid[2];
290     EXPECT_EQ(pthread_rwlock_init(&w_rwlock5, NULL), 0);
291 
292     EXPECT_EQ(pthread_create(&tid[0], NULL, RwlockClockMonotonicTimeOut1, NULL), 0);
293     EXPECT_EQ(pthread_create(&tid[1], NULL, RwlockClockMonotonicTimeOut2, NULL), 0);
294 
295     EXPECT_EQ(pthread_join(tid[0], NULL), 0);
296     EXPECT_EQ(pthread_join(tid[1], NULL), 0);
297     EXPECT_EQ(pthread_rwlock_destroy(&w_rwlock5), 0);
298 }
299 
300 /**
301  * @tc.number    : pthread_rwlock_timedwrlock_0080
302  * @tc.desc      : Test the case of pthread_cond_clockwait timeout by CLOCK_MONOTONIC
303  * @tc.level     : Level 1
304  */
pthread_rwlock_timedwrlock_0080(void)305 void pthread_rwlock_timedwrlock_0080(void)
306 {
307     pthread_t tid[2];
308     EXPECT_EQ(pthread_rwlock_init(&w_rwlock6, NULL), 0);
309 
310     EXPECT_EQ(pthread_create(&tid[0], NULL, RwlockClockMonotonicTimeWait1, NULL), 0);
311     EXPECT_EQ(pthread_create(&tid[1], NULL, RwlockClockMonotonicTimeWait2, NULL), 0);
312 
313     EXPECT_EQ(pthread_join(tid[0], NULL), 0);
314     EXPECT_EQ(pthread_join(tid[1], NULL), 0);
315     EXPECT_EQ(pthread_rwlock_destroy(&w_rwlock6), 0);
316 }
317 
318 /**
319  * @tc.number    : pthread_rwlock_timedwrlock_0090
320  * @tc.desc      : Test the case of pthread_rwlock_timedwrlock_monotonic_np no timeout
321  * @tc.level     : Level 1
322  */
pthread_rwlock_timedwrlock_0090(void)323 void pthread_rwlock_timedwrlock_0090(void)
324 {
325     pthread_t tid[2];
326     EXPECT_EQ(pthread_rwlock_init(&w_rwlock3, NULL), 0);
327 
328     EXPECT_EQ(pthread_create(&tid[0], NULL, RwlockMonotonicTime1, NULL), 0);
329     EXPECT_EQ(pthread_create(&tid[1], NULL, RwlockMonotonicTime2, NULL), 0);
330 
331     EXPECT_EQ(pthread_join(tid[0], NULL), 0);
332     EXPECT_EQ(pthread_join(tid[1], NULL), 0);
333     EXPECT_EQ(pthread_rwlock_destroy(&w_rwlock3), 0);
334 }
335 
336 /**
337  * @tc.number    : pthread_rwlock_timedwrlock_0100
338  * @tc.desc      : Test the case of pthread_rwlock_timedwrlock_monotonic_np timeout
339  * @tc.level     : Level 1
340  */
pthread_rwlock_timedwrlock_0100(void)341 void pthread_rwlock_timedwrlock_0100(void)
342 {
343     pthread_t tid[2];
344     EXPECT_EQ(pthread_rwlock_init(&w_rwlock4, NULL), 0);
345 
346     EXPECT_EQ(pthread_create(&tid[0], NULL, RwlockMonotonicTime3, NULL), 0);
347     EXPECT_EQ(pthread_create(&tid[1], NULL, RwlockMonotonicTime4, NULL), 0);
348 
349     EXPECT_EQ(pthread_join(tid[0], NULL), 0);
350     EXPECT_EQ(pthread_join(tid[1], NULL), 0);
351     EXPECT_EQ(pthread_rwlock_destroy(&w_rwlock4), 0);
352 }
353 
354 /**
355  * @tc.number    : pthread_rwlock_timedwrlock_0110
356  * @tc.desc      : Test the case of pthread_rwlock_timedwrlock_monotonic_np with invalid rwlock
357  * @tc.level     : Level 2
358  */
pthread_rwlock_timedwrlock_0110(void)359 void pthread_rwlock_timedwrlock_0110(void)
360 {
361     struct timespec ts = {0};
362     EXPECT_EQ(pthread_rwlock_timedwrlock_monotonic_np((pthread_rwlock_t *)NULL, &ts), EINVAL);
363 }
364 
365 TEST_FUN G_Fun_Array[] = {
366     pthread_rwlock_timedwrlock_0010,
367     pthread_rwlock_timedwrlock_0020,
368     pthread_rwlock_timedwrlock_0030,
369     pthread_rwlock_timedwrlock_0040,
370     pthread_rwlock_timedwrlock_0050,
371     pthread_rwlock_timedwrlock_0060,
372     pthread_rwlock_timedwrlock_0070,
373     pthread_rwlock_timedwrlock_0080,
374     pthread_rwlock_timedwrlock_0090,
375     pthread_rwlock_timedwrlock_0100,
376     pthread_rwlock_timedwrlock_0110,
377 };
378 
main(void)379 int main(void)
380 {
381     int num = sizeof(G_Fun_Array) / sizeof(TEST_FUN);
382     for (int pos = 0; pos < num; ++pos) {
383         G_Fun_Array[pos]();
384     }
385     return t_status;
386 }