1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci#include <errno.h>
16570af302Sopenharmony_ci#include <pthread.h>
17570af302Sopenharmony_ci#include "pthread_util.h"
18570af302Sopenharmony_ci
19570af302Sopenharmony_ci/********************************************* Test case dividing line ***********************************************/
20570af302Sopenharmony_ci
21570af302Sopenharmony_cipthread_rwlock_t g_rwlock1;
22570af302Sopenharmony_ci
23570af302Sopenharmony_cistatic void *PthreadClockRdlockNoOutRealTimeW1(void *arg)
24570af302Sopenharmony_ci{
25570af302Sopenharmony_ci    TEST(pthread_rwlock_wrlock(&g_rwlock1) == 0);
26570af302Sopenharmony_ci    Msleep(SLEEP_50_MS);
27570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock1) == 0);
28570af302Sopenharmony_ci    return arg;
29570af302Sopenharmony_ci}
30570af302Sopenharmony_ci
31570af302Sopenharmony_cistatic void *PthreadClockRdlockNoOutRealTimeR2(void *arg)
32570af302Sopenharmony_ci{
33570af302Sopenharmony_ci    struct timespec ts = {0};
34570af302Sopenharmony_ci    Msleep(SLEEP_20_MS);
35570af302Sopenharmony_ci    GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_REALTIME);
36570af302Sopenharmony_ci    TEST(pthread_rwlock_clockrdlock(&g_rwlock1, CLOCK_REALTIME, &ts) == 0);
37570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock1) == 0);
38570af302Sopenharmony_ci    return arg;
39570af302Sopenharmony_ci}
40570af302Sopenharmony_ci
41570af302Sopenharmony_ci/**
42570af302Sopenharmony_ci * @tc.name     : pthread_rwlock_clockrdlock_0010
43570af302Sopenharmony_ci * @tc.desc     : test pthread_rwlock_clockrdlock with no timeout by CLOCK_REALTIME , write - read
44570af302Sopenharmony_ci * @tc.level    : Level 0
45570af302Sopenharmony_ci */
46570af302Sopenharmony_cistatic void pthread_rwlock_clockrdlock_0010(void)
47570af302Sopenharmony_ci{
48570af302Sopenharmony_ci    pthread_t tid[2];
49570af302Sopenharmony_ci    TEST(pthread_rwlock_init(&g_rwlock1, NULL) == 0);
50570af302Sopenharmony_ci
51570af302Sopenharmony_ci    TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockNoOutRealTimeW1, NULL) == 0);
52570af302Sopenharmony_ci    TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockNoOutRealTimeR2, NULL) == 0);
53570af302Sopenharmony_ci
54570af302Sopenharmony_ci    TEST(pthread_join(tid[0], NULL) == 0);
55570af302Sopenharmony_ci    TEST(pthread_join(tid[1], NULL) == 0);
56570af302Sopenharmony_ci    TEST(pthread_rwlock_destroy(&g_rwlock1) == 0);
57570af302Sopenharmony_ci}
58570af302Sopenharmony_ci
59570af302Sopenharmony_ci/********************************************* Test case dividing line ***********************************************/
60570af302Sopenharmony_ci
61570af302Sopenharmony_cipthread_rwlock_t g_rwlock2;
62570af302Sopenharmony_ci
63570af302Sopenharmony_cistatic void *PthreadClockRdlockOutRealTimeW1(void *arg)
64570af302Sopenharmony_ci{
65570af302Sopenharmony_ci    TEST(pthread_rwlock_wrlock(&g_rwlock2) == 0);
66570af302Sopenharmony_ci    Msleep(SLEEP_50_MS);
67570af302Sopenharmony_ci    Msleep(SLEEP_100_MS);
68570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock2) == 0);
69570af302Sopenharmony_ci    return arg;
70570af302Sopenharmony_ci}
71570af302Sopenharmony_ci
72570af302Sopenharmony_cistatic void *PthreadClockRdlockOutRealTimeR2(void *arg)
73570af302Sopenharmony_ci{
74570af302Sopenharmony_ci    struct timespec ts = {0};
75570af302Sopenharmony_ci    struct timespec tsNow = {0};
76570af302Sopenharmony_ci    Msleep(SLEEP_20_MS);
77570af302Sopenharmony_ci    GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_REALTIME);
78570af302Sopenharmony_ci    TEST(pthread_rwlock_clockrdlock(&g_rwlock2, CLOCK_REALTIME, &ts) == ETIMEDOUT);
79570af302Sopenharmony_ci    clock_gettime(CLOCK_REALTIME, &tsNow);
80570af302Sopenharmony_ci    int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
81570af302Sopenharmony_ci    TEST(timeDiff < 20);
82570af302Sopenharmony_ci    return arg;
83570af302Sopenharmony_ci}
84570af302Sopenharmony_ci
85570af302Sopenharmony_ci/**
86570af302Sopenharmony_ci * @tc.name     : pthread_rwlock_clockrdlock_0020
87570af302Sopenharmony_ci * @tc.desc     : test pthread_rwlock_clockrdlock with timeout by CLOCK_REALTIME, write - read
88570af302Sopenharmony_ci * @tc.level    : Level 0
89570af302Sopenharmony_ci */
90570af302Sopenharmony_cistatic void pthread_rwlock_clockrdlock_0020(void)
91570af302Sopenharmony_ci{
92570af302Sopenharmony_ci    pthread_t tid[2];
93570af302Sopenharmony_ci    TEST(pthread_rwlock_init(&g_rwlock2, NULL) == 0);
94570af302Sopenharmony_ci
95570af302Sopenharmony_ci    TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockOutRealTimeW1, NULL) == 0);
96570af302Sopenharmony_ci    TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockOutRealTimeR2, NULL) == 0);
97570af302Sopenharmony_ci
98570af302Sopenharmony_ci    TEST(pthread_join(tid[0], NULL) == 0);
99570af302Sopenharmony_ci    TEST(pthread_join(tid[1], NULL) == 0);
100570af302Sopenharmony_ci    TEST(pthread_rwlock_destroy(&g_rwlock2) == 0);
101570af302Sopenharmony_ci}
102570af302Sopenharmony_ci
103570af302Sopenharmony_ci
104570af302Sopenharmony_ci/********************************************* Test case dividing line ***********************************************/
105570af302Sopenharmony_ci
106570af302Sopenharmony_cipthread_rwlock_t g_rwlock3;
107570af302Sopenharmony_ci
108570af302Sopenharmony_cistatic void *PthreadClockRdlockNoOutMonoTimeW1(void *arg)
109570af302Sopenharmony_ci{
110570af302Sopenharmony_ci    TEST(pthread_rwlock_wrlock(&g_rwlock3) == 0);
111570af302Sopenharmony_ci    Msleep(SLEEP_50_MS);
112570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock3) == 0);
113570af302Sopenharmony_ci    return arg;
114570af302Sopenharmony_ci}
115570af302Sopenharmony_ci
116570af302Sopenharmony_cistatic void *PthreadClockRdlockNoOutMonoTimeR2(void *arg)
117570af302Sopenharmony_ci{
118570af302Sopenharmony_ci    struct timespec ts = {0};
119570af302Sopenharmony_ci    Msleep(SLEEP_20_MS);
120570af302Sopenharmony_ci    GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
121570af302Sopenharmony_ci    TEST(pthread_rwlock_clockrdlock(&g_rwlock3, CLOCK_MONOTONIC, &ts) == 0);
122570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock3) == 0);
123570af302Sopenharmony_ci    return arg;
124570af302Sopenharmony_ci}
125570af302Sopenharmony_ci
126570af302Sopenharmony_ci/**
127570af302Sopenharmony_ci * @tc.name     : pthread_rwlock_clockrdlock_0030
128570af302Sopenharmony_ci * @tc.desc     : test pthread_rwlock_clockrdlock with no timeout by CLOCK_MONOTONIC , write - read
129570af302Sopenharmony_ci * @tc.level    : Level 0
130570af302Sopenharmony_ci */
131570af302Sopenharmony_cistatic void pthread_rwlock_clockrdlock_0030(void)
132570af302Sopenharmony_ci{
133570af302Sopenharmony_ci    pthread_t tid[2];
134570af302Sopenharmony_ci    TEST(pthread_rwlock_init(&g_rwlock3, NULL) == 0);
135570af302Sopenharmony_ci
136570af302Sopenharmony_ci    TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockNoOutMonoTimeW1, NULL) == 0);
137570af302Sopenharmony_ci    TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockNoOutMonoTimeR2, NULL) == 0);
138570af302Sopenharmony_ci
139570af302Sopenharmony_ci    TEST(pthread_join(tid[0], NULL) == 0);
140570af302Sopenharmony_ci    TEST(pthread_join(tid[1], NULL) == 0);
141570af302Sopenharmony_ci    TEST(pthread_rwlock_destroy(&g_rwlock3) == 0);
142570af302Sopenharmony_ci}
143570af302Sopenharmony_ci
144570af302Sopenharmony_ci/********************************************* Test case dividing line ***********************************************/
145570af302Sopenharmony_ci
146570af302Sopenharmony_cipthread_rwlock_t g_rwlock4;
147570af302Sopenharmony_ci
148570af302Sopenharmony_cistatic void *PthreadClockRdlockOutMonoTimeW1(void *arg)
149570af302Sopenharmony_ci{
150570af302Sopenharmony_ci    TEST(pthread_rwlock_wrlock(&g_rwlock4) == 0);
151570af302Sopenharmony_ci    Msleep(SLEEP_50_MS);
152570af302Sopenharmony_ci    Msleep(SLEEP_100_MS);
153570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock4) == 0);
154570af302Sopenharmony_ci    return arg;
155570af302Sopenharmony_ci}
156570af302Sopenharmony_ci
157570af302Sopenharmony_cistatic void *PthreadClockRdlockOutMonoTimeR2(void *arg)
158570af302Sopenharmony_ci{
159570af302Sopenharmony_ci    struct timespec ts = {0};
160570af302Sopenharmony_ci    struct timespec tsNow = {0};
161570af302Sopenharmony_ci    Msleep(SLEEP_20_MS);
162570af302Sopenharmony_ci    GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
163570af302Sopenharmony_ci    TEST(pthread_rwlock_clockrdlock(&g_rwlock4, CLOCK_MONOTONIC, &ts) == ETIMEDOUT);
164570af302Sopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &tsNow);
165570af302Sopenharmony_ci    int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
166570af302Sopenharmony_ci    TEST(timeDiff < 20);
167570af302Sopenharmony_ci    return arg;
168570af302Sopenharmony_ci}
169570af302Sopenharmony_ci
170570af302Sopenharmony_ci/**
171570af302Sopenharmony_ci * @tc.name     : pthread_rwlock_clockrdlock_0040
172570af302Sopenharmony_ci * @tc.desc     : test pthread_rwlock_clockrdlock with timeout by CLOCK_MONOTONIC, write - read
173570af302Sopenharmony_ci * @tc.level    : Level 0
174570af302Sopenharmony_ci */
175570af302Sopenharmony_cistatic void pthread_rwlock_clockrdlock_0040(void)
176570af302Sopenharmony_ci{
177570af302Sopenharmony_ci    pthread_t tid[2];
178570af302Sopenharmony_ci    TEST(pthread_rwlock_init(&g_rwlock4, NULL) == 0);
179570af302Sopenharmony_ci
180570af302Sopenharmony_ci    TEST(pthread_create(&tid[0], NULL, PthreadClockRdlockOutMonoTimeW1, NULL) == 0);
181570af302Sopenharmony_ci    TEST(pthread_create(&tid[1], NULL, PthreadClockRdlockOutMonoTimeR2, NULL) == 0);
182570af302Sopenharmony_ci
183570af302Sopenharmony_ci    TEST(pthread_join(tid[0], NULL) == 0);
184570af302Sopenharmony_ci    TEST(pthread_join(tid[1], NULL) == 0);
185570af302Sopenharmony_ci    TEST(pthread_rwlock_destroy(&g_rwlock4) == 0);
186570af302Sopenharmony_ci}
187570af302Sopenharmony_ci
188570af302Sopenharmony_ci/********************************************* Test case dividing line ***********************************************/
189570af302Sopenharmony_ci
190570af302Sopenharmony_cipthread_rwlock_t g_rwlock5;
191570af302Sopenharmony_ci
192570af302Sopenharmony_cistatic void *PthreadTimedRdlockMonoNPNoOutW1(void *arg)
193570af302Sopenharmony_ci{
194570af302Sopenharmony_ci    TEST(pthread_rwlock_wrlock(&g_rwlock5) == 0);
195570af302Sopenharmony_ci    Msleep(SLEEP_50_MS);
196570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock5) == 0);
197570af302Sopenharmony_ci    return arg;
198570af302Sopenharmony_ci}
199570af302Sopenharmony_ci
200570af302Sopenharmony_cistatic void *PthreadTimedRdlockMonoNPNoOutR2(void *arg)
201570af302Sopenharmony_ci{
202570af302Sopenharmony_ci    struct timespec ts = {0};
203570af302Sopenharmony_ci    Msleep(SLEEP_20_MS);
204570af302Sopenharmony_ci    GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
205570af302Sopenharmony_ci    TEST(pthread_rwlock_timedrdlock_monotonic_np(&g_rwlock5, &ts) == 0);
206570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock5) == 0);
207570af302Sopenharmony_ci    return arg;
208570af302Sopenharmony_ci}
209570af302Sopenharmony_ci
210570af302Sopenharmony_ci/**
211570af302Sopenharmony_ci * @tc.name     : pthread_rwlock_timedrdlock_monotonic_np_0010
212570af302Sopenharmony_ci * @tc.desc     : test pthread_rwlock_timedrdlock_monotonic_np with no timeout by CLOCK_MONOTONIC, write - read
213570af302Sopenharmony_ci * @tc.level    : Level 0
214570af302Sopenharmony_ci */
215570af302Sopenharmony_cistatic void pthread_rwlock_timedrdlock_monotonic_np_0010(void)
216570af302Sopenharmony_ci{
217570af302Sopenharmony_ci    pthread_t tid[2];
218570af302Sopenharmony_ci    TEST(pthread_rwlock_init(&g_rwlock5, NULL) == 0);
219570af302Sopenharmony_ci
220570af302Sopenharmony_ci    TEST(pthread_create(&tid[0], NULL, PthreadTimedRdlockMonoNPNoOutW1, NULL) == 0);
221570af302Sopenharmony_ci    TEST(pthread_create(&tid[1], NULL, PthreadTimedRdlockMonoNPNoOutR2, NULL) == 0);
222570af302Sopenharmony_ci
223570af302Sopenharmony_ci    TEST(pthread_join(tid[0], NULL) == 0);
224570af302Sopenharmony_ci    TEST(pthread_join(tid[1], NULL) == 0);
225570af302Sopenharmony_ci    TEST(pthread_rwlock_destroy(&g_rwlock5) == 0);
226570af302Sopenharmony_ci}
227570af302Sopenharmony_ci
228570af302Sopenharmony_ci/********************************************* Test case dividing line ***********************************************/
229570af302Sopenharmony_ci
230570af302Sopenharmony_cipthread_rwlock_t g_rwlock6;
231570af302Sopenharmony_ci
232570af302Sopenharmony_cistatic void *PthreadTimedRdlockMonoNPOutW1(void *arg)
233570af302Sopenharmony_ci{
234570af302Sopenharmony_ci    TEST(pthread_rwlock_wrlock(&g_rwlock6) == 0);
235570af302Sopenharmony_ci    Msleep(SLEEP_50_MS);
236570af302Sopenharmony_ci    Msleep(SLEEP_100_MS);
237570af302Sopenharmony_ci    TEST(pthread_rwlock_unlock(&g_rwlock6) == 0);
238570af302Sopenharmony_ci    return arg;
239570af302Sopenharmony_ci}
240570af302Sopenharmony_ci
241570af302Sopenharmony_cistatic void *PthreadTimedRdlockMonoNPOutR2(void *arg)
242570af302Sopenharmony_ci{
243570af302Sopenharmony_ci    struct timespec ts = {0};
244570af302Sopenharmony_ci    struct timespec tsNow = {0};
245570af302Sopenharmony_ci    Msleep(SLEEP_20_MS);
246570af302Sopenharmony_ci    GetDelayedTimeByClockid(&ts, DELAY_TIME_100_MS, CLOCK_MONOTONIC);
247570af302Sopenharmony_ci    TEST(pthread_rwlock_timedrdlock_monotonic_np(&g_rwlock6, &ts) == ETIMEDOUT);
248570af302Sopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &tsNow);
249570af302Sopenharmony_ci    int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different
250570af302Sopenharmony_ci    TEST(timeDiff < 20);
251570af302Sopenharmony_ci    return arg;
252570af302Sopenharmony_ci}
253570af302Sopenharmony_ci
254570af302Sopenharmony_ci/**
255570af302Sopenharmony_ci * @tc.name     : pthread_rwlock_timedrdlock_monotonic_np_0020
256570af302Sopenharmony_ci * @tc.desc     : test pthread_rwlock_timedrdlock_monotonic_np with timeout by CLOCK_MONOTONIC, write - read
257570af302Sopenharmony_ci * @tc.level    : Level 0
258570af302Sopenharmony_ci */
259570af302Sopenharmony_cistatic void pthread_rwlock_timedrdlock_monotonic_np_0020(void)
260570af302Sopenharmony_ci{
261570af302Sopenharmony_ci    pthread_t tid[2];
262570af302Sopenharmony_ci    TEST(pthread_rwlock_init(&g_rwlock6, NULL) == 0);
263570af302Sopenharmony_ci
264570af302Sopenharmony_ci    TEST(pthread_create(&tid[0], NULL, PthreadTimedRdlockMonoNPOutW1, NULL) == 0);
265570af302Sopenharmony_ci    TEST(pthread_create(&tid[1], NULL, PthreadTimedRdlockMonoNPOutR2, NULL) == 0);
266570af302Sopenharmony_ci
267570af302Sopenharmony_ci    TEST(pthread_join(tid[0], NULL) == 0);
268570af302Sopenharmony_ci    TEST(pthread_join(tid[1], NULL) == 0);
269570af302Sopenharmony_ci    TEST(pthread_rwlock_destroy(&g_rwlock6) == 0);
270570af302Sopenharmony_ci}
271570af302Sopenharmony_ci
272570af302Sopenharmony_ci/**
273570af302Sopenharmony_ci * @tc.name     : pthread_rwlock_timedrdlock_monotonic_np_0030
274570af302Sopenharmony_ci * @tc.desc     : test pthread_rwlock_timedrdlock_monotonic_np with invalid rwlock
275570af302Sopenharmony_ci * @tc.level    : Level 2
276570af302Sopenharmony_ci */
277570af302Sopenharmony_cistatic void pthread_rwlock_timedrdlock_monotonic_np_0030(void)
278570af302Sopenharmony_ci{
279570af302Sopenharmony_ci    struct timespec ts = {0};
280570af302Sopenharmony_ci    EXPECT_EQ(pthread_rwlock_timedrdlock_monotonic_np((pthread_rwlock_t *)NULL, &ts), EINVAL);
281570af302Sopenharmony_ci}
282570af302Sopenharmony_ci
283570af302Sopenharmony_ciint main(void)
284570af302Sopenharmony_ci{
285570af302Sopenharmony_ci    pthread_rwlock_clockrdlock_0010();
286570af302Sopenharmony_ci    pthread_rwlock_clockrdlock_0020();
287570af302Sopenharmony_ci    pthread_rwlock_clockrdlock_0030();
288570af302Sopenharmony_ci    pthread_rwlock_clockrdlock_0040();
289570af302Sopenharmony_ci    pthread_rwlock_timedrdlock_monotonic_np_0010();
290570af302Sopenharmony_ci    pthread_rwlock_timedrdlock_monotonic_np_0020();
291570af302Sopenharmony_ci    pthread_rwlock_timedrdlock_monotonic_np_0030();
292570af302Sopenharmony_ci
293570af302Sopenharmony_ci	return t_status;
294570af302Sopenharmony_ci}