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 21pthread_rwlock_t g_rwlock1; 22 23static 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 31static 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 */ 46static 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 61pthread_rwlock_t g_rwlock2; 62 63static 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 72static 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 */ 90static 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 106pthread_rwlock_t g_rwlock3; 107 108static 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 116static 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 */ 131static 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 146pthread_rwlock_t g_rwlock4; 147 148static 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 157static 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 */ 175static 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 190pthread_rwlock_t g_rwlock5; 191 192static 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 200static 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 */ 215static 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 230pthread_rwlock_t g_rwlock6; 231 232static 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 241static 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 */ 259static 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 */ 277static 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 283int 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}