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
20static pthread_rwlock_t w_rwlock1;
21static pthread_rwlock_t w_rwlock2;
22static pthread_rwlock_t w_rwlock3;
23static pthread_rwlock_t w_rwlock4;
24static pthread_rwlock_t w_rwlock5;
25static pthread_rwlock_t w_rwlock6;
26
27static 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
36static 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
56static 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
64static 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
75static 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
84static 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
106static 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
114static 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
124static 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
133static 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
155static 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
163static 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
179void 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 */
196void 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 */
215void 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 */
234void 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 */
251void 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 */
269void 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 */
287void 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 */
305void 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 */
323void 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 */
341void 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 */
359void 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
365TEST_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
379int 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}