1/* 2 * Copyright (c) 2021 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 16#include <stdio.h> 17#include <string.h> 18#include <stdlib.h> 19#include <time.h> 20#include <unistd.h> 21#include <pthread.h> 22#include <sys/time.h> 23#include <gtest/gtest.h> 24#include "utils.h" 25#include "mt_utils.h" 26#include "log.h" 27#include "FutexTest.h" 28 29using namespace testing::ext; 30 31/********************************************* Test case dividing line ***********************************************/ 32 33pthread_rwlock_t g_rwlock1; 34 35void *PthreadRWlockWW1(void *arg) 36{ 37 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock1), 0) << "> return errno"; 38 Msleep(50); 39 CheckStep(2); 40 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock1), 0) << "> return errno"; 41 return arg; 42} 43 44void *PthreadRWlockWW2(void *arg) 45{ 46 Msleep(20); 47 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock1), 0) << "> return errno"; 48 CheckStep(3); 49 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock1), 0) << "> return errno"; 50 return arg; 51} 52 53/** 54 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0100 55 * @tc.name test rdlock and wrlock, write - write 56 * @tc.desc [C- SOFTWARE -0200] 57 */ 58HWTEST_F(FutexTest, testPthreadRWlockWW, Function | MediumTest | Level3) 59{ 60 pthread_t tid[2]; 61 CheckStep(1); 62 EXPECT_EQ(pthread_rwlock_init(&g_rwlock1, nullptr), 0); 63 64 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockWW1, nullptr), 0) << "> return errno"; 65 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockWW2, nullptr), 0) << "> return errno"; 66 67 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 68 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 69 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 70 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock1), 0); 71} 72 73/********************************************* Test case dividing line ***********************************************/ 74 75pthread_rwlock_t g_rwlock2; 76 77void *PthreadRWlockWR1(void *arg) 78{ 79 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock2), 0) << "> return errno"; 80 Msleep(50); 81 CheckStep(2); 82 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock2), 0) << "> return errno"; 83 return arg; 84} 85 86void *PthreadRWlockWR2(void *arg) 87{ 88 Msleep(20); 89 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock2), 0) << "> return errno"; 90 CheckStep(3); 91 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock2), 0) << "> return errno"; 92 return arg; 93} 94 95/** 96 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0200 97 * @tc.name test rdlock and wrlock, write - read 98 * @tc.desc [C- SOFTWARE -0200] 99 */ 100HWTEST_F(FutexTest, testPthreadRWlockWR, Function | MediumTest | Level3) 101{ 102 pthread_t tid[2]; 103 CheckStep(1); 104 EXPECT_EQ(pthread_rwlock_init(&g_rwlock2, nullptr), 0); 105 106 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockWR1, nullptr), 0) << "> return errno"; 107 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockWR2, nullptr), 0) << "> return errno"; 108 109 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 110 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 111 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 112 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock2), 0); 113} 114 115/********************************************* Test case dividing line ***********************************************/ 116 117pthread_rwlock_t g_rwlock3; 118 119void *PthreadRWlockRR1(void *arg) 120{ 121 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock3), 0) << "> return errno"; 122 Msleep(50); 123 CheckStep(3); 124 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock3), 0) << "> return errno"; 125 return arg; 126} 127 128void *PthreadRWlockRR2(void *arg) 129{ 130 Msleep(20); 131 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock3), 0) << "> return errno"; 132 CheckStep(2); 133 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock3), 0) << "> return errno"; 134 return arg; 135} 136 137/** 138 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0300 139 * @tc.name test rdlock and wrlock, read - read 140 * @tc.desc [C- SOFTWARE -0200] 141 */ 142HWTEST_F(FutexTest, testPthreadRWlockRR, Function | MediumTest | Level3) 143{ 144 pthread_t tid[2]; 145 CheckStep(1); 146 EXPECT_EQ(pthread_rwlock_init(&g_rwlock3, nullptr), 0); 147 148 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockRR1, nullptr), 0) << "> return errno"; 149 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockRR2, nullptr), 0) << "> return errno"; 150 151 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 152 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 153 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 154 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock3), 0); 155} 156 157/********************************************* Test case dividing line ***********************************************/ 158 159pthread_rwlock_t g_rwlock4; 160 161void *PthreadRWlockRW1(void *arg) 162{ 163 EXPECT_EQ(pthread_rwlock_rdlock(&g_rwlock4), 0) << "> return errno"; 164 Msleep(50); 165 CheckStep(2); 166 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock4), 0) << "> return errno"; 167 return arg; 168} 169 170void *PthreadRWlockRW2(void *arg) 171{ 172 Msleep(20); 173 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock4), 0) << "> return errno"; 174 CheckStep(3); 175 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock4), 0) << "> return errno"; 176 return arg; 177} 178 179/** 180 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0400 181 * @tc.name test rdlock and wrlock, read - write 182 * @tc.desc [C- SOFTWARE -0200] 183 */ 184HWTEST_F(FutexTest, testPthreadRWlockRW, Function | MediumTest | Level3) 185{ 186 pthread_t tid[2]; 187 CheckStep(1); 188 EXPECT_EQ(pthread_rwlock_init(&g_rwlock4, nullptr), 0); 189 190 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWlockRW1, nullptr), 0) << "> return errno"; 191 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWlockRW2, nullptr), 0) << "> return errno"; 192 193 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 194 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 195 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 196 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock4), 0); 197} 198 199/********************************************* Test case dividing line ***********************************************/ 200 201pthread_rwlock_t g_rwlock5; 202 203void *PthreadRWtrylockWR1(void *arg) 204{ 205 EXPECT_EQ(pthread_rwlock_trywrlock(&g_rwlock5), 0) << "> return errno"; 206 Msleep(50); 207 CheckStep(3); 208 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock5), 0) << "> return errno"; 209 return arg; 210} 211 212void *PthreadRWtrylockWR2(void *arg) 213{ 214 Msleep(20); 215 EXPECT_EQ(pthread_rwlock_tryrdlock(&g_rwlock5), EBUSY) << "> should return EBUSY"; 216 CheckStep(2); 217 return arg; 218} 219 220/** 221 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0500 222 * @tc.name test tryrdlock and trywrlock, write - read 223 * @tc.desc [C- SOFTWARE -0200] 224 */ 225HWTEST_F(FutexTest, testPthreadRWtrylockWR, Function | MediumTest | Level3) 226{ 227 pthread_t tid[2]; 228 CheckStep(1); 229 EXPECT_EQ(pthread_rwlock_init(&g_rwlock5, nullptr), 0); 230 231 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWtrylockWR1, nullptr), 0) << "> return errno"; 232 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWtrylockWR2, nullptr), 0) << "> return errno"; 233 234 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 235 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 236 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 237 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock5), 0); 238} 239 240/********************************************* Test case dividing line ***********************************************/ 241 242pthread_rwlock_t g_rwlock6; 243 244void *PthreadRWtrylockRW1(void *arg) 245{ 246 EXPECT_EQ(pthread_rwlock_tryrdlock(&g_rwlock6), 0) << "> return errno"; 247 Msleep(50); 248 CheckStep(3); 249 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock6), 0) << "> return errno"; 250 return arg; 251} 252 253void *PthreadRWtrylockRW2(void *arg) 254{ 255 Msleep(20); 256 EXPECT_EQ(pthread_rwlock_trywrlock(&g_rwlock6), EBUSY) << "> should return EBUSY"; 257 CheckStep(2); 258 return arg; 259} 260 261/** 262 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0600 263 * @tc.name test tryrdlock and trywrlock, read - write 264 * @tc.desc [C- SOFTWARE -0200] 265 */ 266HWTEST_F(FutexTest, testPthreadRWtrylockRW, Function | MediumTest | Level3) 267{ 268 pthread_t tid[2]; 269 CheckStep(1); 270 EXPECT_EQ(pthread_rwlock_init(&g_rwlock6, nullptr), 0); 271 272 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadRWtrylockRW1, nullptr), 0) << "> return errno"; 273 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadRWtrylockRW2, nullptr), 0) << "> return errno"; 274 275 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 276 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 277 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 278 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock6), 0); 279} 280 281/********************************************* Test case dividing line ***********************************************/ 282 283pthread_rwlock_t g_rwlock7; 284 285void *PthreadTimdNoOutRWlockWR1(void *arg) 286{ 287 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock7), 0) << "> return errno"; 288 Msleep(50); 289 CheckStep(2); 290 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock7), 0) << "> return errno"; 291 return arg; 292} 293 294void *PthreadTimdNoOutRWlockWR2(void *arg) 295{ 296 struct timespec ts = {0}; 297 Msleep(20); 298 GetDelayedTime(&ts, 100); 299 EXPECT_EQ(pthread_rwlock_timedrdlock(&g_rwlock7, &ts), 0) << "> return errno"; 300 CheckStep(3); 301 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock7), 0) << "> return errno"; 302 return arg; 303} 304 305/** 306 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0700 307 * @tc.name test pthread_rwlock_timedrdlock with no timeout , write - read 308 * @tc.desc [C- SOFTWARE -0200] 309 */ 310HWTEST_F(FutexTest, testPthreadTimdNoOutRWlockWR, Function | MediumTest | Level3) 311{ 312 pthread_t tid[2]; 313 CheckStep(1); 314 EXPECT_EQ(pthread_rwlock_init(&g_rwlock7, nullptr), 0); 315 316 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdNoOutRWlockWR1, nullptr), 0) << "> return errno"; 317 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdNoOutRWlockWR2, nullptr), 0) << "> return errno"; 318 319 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 320 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 321 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 322 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock7), 0); 323} 324 325/********************************************* Test case dividing line ***********************************************/ 326 327pthread_rwlock_t g_rwlock8; 328 329void *PthreadTimdOutRWlockWR1(void *arg) 330{ 331 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock8), 0) << "> return errno"; 332 Msleep(50); 333 CheckStep(2); 334 Msleep(100); 335 CheckStep(4); 336 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock8), 0) << "> return errno"; 337 return arg; 338} 339 340void *PthreadTimdOutRWlockWR2(void *arg) 341{ 342 struct timespec ts = {0}; 343 struct timespec tsNow = {0}; 344 Msleep(20); 345 GetDelayedTime(&ts, 100); 346 EXPECT_EQ(pthread_rwlock_timedrdlock(&g_rwlock8, &ts), ETIMEDOUT) << "> return errno"; 347 CheckStep(3); 348 clock_gettime(CLOCK_REALTIME, &tsNow); 349 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different 350 EXPECT_GE(timeDiff, 0); 351 EXPECT_LE(timeDiff, 20); 352 return arg; 353} 354 355/** 356 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0800 357 * @tc.name test pthread_rwlock_timedrdlock with timeout, write - read 358 * @tc.desc [C- SOFTWARE -0200] 359 */ 360HWTEST_F(FutexTest, testPthreadTimdOutRWlockWR, Function | MediumTest | Level3) 361{ 362 pthread_t tid[2]; 363 CheckStep(1); 364 EXPECT_EQ(pthread_rwlock_init(&g_rwlock8, nullptr), 0); 365 366 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdOutRWlockWR1, nullptr), 0) << "> return errno"; 367 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdOutRWlockWR2, nullptr), 0) << "> return errno"; 368 369 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 370 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 371 EXPECT_EQ(CheckStep(5), (uint64_t)0x12345); 372 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock8), 0); 373} 374 375/********************************************* Test case dividing line ***********************************************/ 376 377pthread_rwlock_t g_rwlock9; 378 379void *PthreadTimdOutRWlockWW1(void *arg) 380{ 381 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlock9), 0) << "> return errno"; 382 Msleep(50); 383 CheckStep(2); 384 Msleep(100); 385 CheckStep(4); 386 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlock9), 0) << "> return errno"; 387 return arg; 388} 389 390void *PthreadTimdOutRWlockWW2(void *arg) 391{ 392 struct timespec ts = {0}; 393 struct timespec tsNow = {0}; 394 Msleep(20); 395 GetDelayedTime(&ts, 100); 396 EXPECT_EQ(pthread_rwlock_timedwrlock(&g_rwlock9, &ts), ETIMEDOUT) << "> return errno"; 397 CheckStep(3); 398 clock_gettime(CLOCK_REALTIME, &tsNow); 399 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different 400 EXPECT_GE(timeDiff, 0); 401 EXPECT_LE(timeDiff, 20); 402 return arg; 403} 404 405/** 406 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_0900 407 * @tc.name test pthread_rwlock_timedwrlock with timeout, write - write 408 * @tc.desc [C- SOFTWARE -0200] 409 */ 410HWTEST_F(FutexTest, testPthreadTimdOutRWlockWW, Function | MediumTest | Level3) 411{ 412 pthread_t tid[2]; 413 CheckStep(1); 414 EXPECT_EQ(pthread_rwlock_init(&g_rwlock9, nullptr), 0); 415 416 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdOutRWlockWW1, nullptr), 0) << "> return errno"; 417 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdOutRWlockWW2, nullptr), 0) << "> return errno"; 418 419 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 420 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 421 EXPECT_EQ(CheckStep(5), (uint64_t)0x12345); 422 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlock9), 0); 423} 424 425/********************************************* Test case dividing line ***********************************************/ 426 427pthread_rwlock_t g_rwlockA; 428 429void *PthreadTimdNoOutRWlockWW1(void *arg) 430{ 431 EXPECT_EQ(pthread_rwlock_wrlock(&g_rwlockA), 0) << "> return errno"; 432 Msleep(50); 433 CheckStep(2); 434 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlockA), 0) << "> return errno"; 435 return arg; 436} 437 438void *PthreadTimdNoOutRWlockWW2(void *arg) 439{ 440 struct timespec ts = {0}; 441 Msleep(20); 442 GetDelayedTime(&ts, 100); 443 EXPECT_EQ(pthread_rwlock_timedwrlock(&g_rwlockA, &ts), 0) << "> return errno"; 444 CheckStep(3); 445 EXPECT_EQ(pthread_rwlock_unlock(&g_rwlockA), 0) << "> return errno"; 446 return arg; 447} 448 449/** 450 * @tc.number SUB_KERNEL_FUTEX_RWLOCK_ALL_1000 451 * @tc.name test pthread_rwlock_timedwrlock with no timeout, write - write 452 * @tc.desc [C- SOFTWARE -0200] 453 */ 454HWTEST_F(FutexTest, testPthreadTimdNoOutRWlockWW, Function | MediumTest | Level3) 455{ 456 pthread_t tid[2]; 457 CheckStep(1); 458 EXPECT_EQ(pthread_rwlock_init(&g_rwlockA, nullptr), 0); 459 460 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadTimdNoOutRWlockWW1, nullptr), 0) << "> return errno"; 461 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadTimdNoOutRWlockWW2, nullptr), 0) << "> return errno"; 462 463 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 464 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 465 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 466 EXPECT_EQ(pthread_rwlock_destroy(&g_rwlockA), 0); 467} 468 469/********************************************* Test case dividing line ***********************************************/ 470 471/** 472 * @tc.number SUB_KERNEL_FUTEX_RWLOCKATTR_0100 473 * @tc.name test pthread_rwlockattr_init api 474 * @tc.desc [C- SOFTWARE -0200] 475 */ 476HWTEST_F(FutexTest, testPthreadRwlockAttr, Function | MediumTest | Level1) 477{ 478 pthread_rwlockattr_t attr; 479 EXPECT_EQ(pthread_rwlockattr_init(&attr), 0); 480 EXPECT_EQ(pthread_rwlockattr_destroy(&attr), 0); 481} 482