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 33void *ThreadMutex(void *arg) 34{ 35 int delayTime = GetRandom(50); 36 pthread_mutex_t *mtx = (pthread_mutex_t *)arg; 37 EXPECT_EQ(pthread_mutex_lock(mtx), 0) << "> return errno"; 38 CheckStep(1); 39 Msleep(delayTime); 40 EXPECT_EQ(CheckStep(2), (uint64_t)0x12); 41 EXPECT_EQ(pthread_mutex_unlock(mtx), 0) << "> return errno"; 42 return arg; 43} 44 45/** 46 * @tc.number SUB_KERNEL_FUTEX_MUTEX_ALL_0100 47 * @tc.name basic test of pthread_mutex 48 * @tc.desc [C- SOFTWARE -0200] 49 */ 50HWTEST_F(FutexTest, testPthreadMutex, Function | MediumTest | Level3) 51{ 52 pthread_mutex_t mtx; 53 const int loopNum = 5; 54 pthread_t tid[loopNum]; 55 56 EXPECT_EQ(pthread_mutex_init(&mtx, nullptr), 0) << "> return errno"; 57 58 for (int i = 0; i < loopNum; i++) { 59 EXPECT_EQ(pthread_create(&tid[i], nullptr, ThreadMutex, (void*)&mtx), 0) << "> return errno"; 60 } 61 for (int i = 0; i < loopNum; i++) { 62 EXPECT_EQ(pthread_join(tid[i], nullptr), 0) << "> return errno"; 63 } 64 EXPECT_EQ(pthread_mutex_destroy(&mtx), 0) << "> return errno"; 65} 66 67/********************************************* Test case dividing line ***********************************************/ 68 69void *ThreadMtrylock1(void *arg) 70{ 71 pthread_mutex_t *mtx = (pthread_mutex_t *)arg; 72 EXPECT_EQ(pthread_mutex_trylock(mtx), 0) << "> return errno"; 73 CheckStep(1); 74 Msleep(50); 75 CheckStep(4); 76 EXPECT_EQ(pthread_mutex_unlock(mtx), 0) << "> return errno"; 77 CheckStep(5); 78 return arg; 79} 80 81void *ThreadMtrylock2(void *arg) 82{ 83 Msleep(20); 84 pthread_mutex_t *mtx = (pthread_mutex_t *)arg; 85 CheckStep(2); 86 EXPECT_EQ(pthread_mutex_trylock(mtx), EBUSY) << "> should return errno"; 87 CheckStep(3); 88 return arg; 89} 90 91/** 92 * @tc.number SUB_KERNEL_FUTEX_MUTEX_ALL_0200 93 * @tc.name basic test of pthread_mutex_trylock 94 * @tc.desc [C- SOFTWARE -0200] 95 */ 96HWTEST_F(FutexTest, testPthreadMtrylock, Function | MediumTest | Level3) 97{ 98 pthread_t tid[2]; 99 pthread_mutex_t mtx; 100 101 EXPECT_EQ(pthread_mutex_init(&mtx, nullptr), 0) << "> return errno"; 102 EXPECT_EQ(pthread_create(&tid[0], nullptr, ThreadMtrylock1, (void*)&mtx), 0) << "> return errno"; 103 EXPECT_EQ(pthread_create(&tid[1], nullptr, ThreadMtrylock2, (void*)&mtx), 0) << "> return errno"; 104 105 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 106 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 107 108 EXPECT_EQ(pthread_mutex_destroy(&mtx), 0) << "> return errno"; 109 EXPECT_EQ(CheckStep(6), (uint64_t)0x123456); 110} 111 112/********************************************* Test case dividing line ***********************************************/ 113 114struct PthreadMutexCond { 115 const int loopNum = 10; 116 const int countMax = 5; 117 int count = 0; 118 int top = 0; 119 int bottom = 0; 120 pthread_cond_t notfull = PTHREAD_COND_INITIALIZER; 121 pthread_cond_t notempty = PTHREAD_COND_INITIALIZER; 122 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 123} g_st1; 124 125void *PthreadProduce(void *arg) 126{ 127 for (int i = 0; i < g_st1.loopNum; i++) { 128 EXPECT_EQ(pthread_mutex_lock(&g_st1.mutex), 0) << "> return errno"; 129 // check full 130 if ((g_st1.top + 1) % g_st1.countMax == g_st1.bottom) { 131 EXPECT_EQ(pthread_cond_wait(&g_st1.notempty, &g_st1.mutex), 0); 132 } 133 // Produce 134 g_st1.top = (g_st1.top + 1) % g_st1.countMax; 135 g_st1.count++; 136 LOG("producer g_st1.top = %d", g_st1.top); 137 138 EXPECT_EQ(pthread_cond_signal(&g_st1.notempty), 0); 139 EXPECT_EQ(pthread_mutex_unlock(&g_st1.mutex), 0) << "> return errno"; 140 Msleep(10); 141 } 142 return arg; 143} 144 145void *PthreadConsume(void *arg) 146{ 147 for (int i = 0; i < g_st1.loopNum; i++) { 148 EXPECT_EQ(pthread_mutex_lock(&g_st1.mutex), 0) << "> return errno"; 149 // check empty 150 if (g_st1.top == g_st1.bottom) { 151 EXPECT_EQ(pthread_cond_wait(&g_st1.notempty, &g_st1.mutex), 0); 152 } 153 // Consume 154 g_st1.bottom = (g_st1.bottom + 1) % g_st1.countMax; 155 g_st1.count--; 156 LOG("consume g_st1.bottom = %d", g_st1.bottom); 157 158 EXPECT_EQ(pthread_cond_signal(&g_st1.notempty), 0); 159 EXPECT_EQ(pthread_mutex_unlock(&g_st1.mutex), 0) << "> return errno"; 160 161 Msleep(10); 162 } 163 return arg; 164} 165 166/** 167 * @tc.number SUB_KERNEL_FUTEX_MUTEX_ALL_0300 168 * @tc.name test pthread_mutex with condition variable, produce and consume 169 * @tc.desc [C- SOFTWARE -0200] 170 */ 171HWTEST_F(FutexTest, testPthreadMutexCond, Function | MediumTest | Level3) 172{ 173 pthread_t tid[2]; 174 g_st1.count = 0; 175 EXPECT_EQ(pthread_create(&tid[0], nullptr, PthreadProduce, nullptr), 0) << "> return errno"; 176 EXPECT_EQ(pthread_create(&tid[1], nullptr, PthreadConsume, nullptr), 0) << "> return errno"; 177 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 178 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 179 EXPECT_EQ(g_st1.count, 0); 180} 181 182/********************************************* Test case dividing line ***********************************************/ 183 184void *ThreadPthreadMtimedlockOut(void *arg) 185{ 186 pthread_mutex_t *mtx = (pthread_mutex_t*)arg; 187 struct timespec ts = {0}; 188 struct timespec tsNow = {0}; 189 190 Msleep(20); 191 CheckStep(1); 192 GetDelayedTime(&ts, 100); 193 EXPECT_EQ(pthread_mutex_timedlock(mtx, &ts), ETIMEDOUT) << "> return should errno"; 194 195 CheckStep(3); 196 clock_gettime(CLOCK_REALTIME, &tsNow); 197 int timeDiff = GetTimeDiff(tsNow, ts); // calculate time different 198 EXPECT_GE(timeDiff, 0); 199 EXPECT_LE(timeDiff, 20); 200 return arg; 201} 202 203/** 204 * @tc.number SUB_KERNEL_FUTEX_PTHREAD_TIMEDLOCK_0100 205 * @tc.name test pthread_mutex_timedlock whith timeout 206 * @tc.desc [C- SOFTWARE -0200] 207 */ 208HWTEST_F(FutexTest, testPthreadMtimedlockOut, Function | MediumTest | Level3) 209{ 210 pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 211 pthread_t tid; 212 EXPECT_EQ(pthread_create(&tid, nullptr, ThreadPthreadMtimedlockOut, (void*)&mtx), 0) << "> return errno"; 213 214 EXPECT_EQ(pthread_mutex_lock(&mtx), 0) << "> return errno"; 215 Msleep(50); 216 CheckStep(2); 217 Msleep(100); 218 CheckStep(4); 219 EXPECT_EQ(pthread_mutex_unlock(&mtx), 0) << "> return errno"; 220 221 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno"; 222 EXPECT_EQ(CheckStep(5), (uint64_t)0x12345); 223} 224 225/********************************************* Test case dividing line ***********************************************/ 226 227void *ThreadPthreadMtimedlockNoOut(void *arg) 228{ 229 pthread_mutex_t *mtx = (pthread_mutex_t*)arg; 230 struct timespec ts = {0}; 231 232 Msleep(20); 233 CheckStep(1); 234 GetDelayedTime(&ts, 100); 235 EXPECT_EQ(pthread_mutex_timedlock(mtx, &ts), 0) << "> return errno"; 236 CheckStep(3); 237 return arg; 238} 239 240/** 241 * @tc.number SUB_KERNEL_FUTEX_PTHREAD_TIMEDLOCK_0200 242 * @tc.name test pthread_mutex_timedlock with no timeout 243 * @tc.desc [C- SOFTWARE -0200] 244 */ 245HWTEST_F(FutexTest, testPthreadMtimedlockNoOut, Function | MediumTest | Level3) 246{ 247 pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 248 pthread_t tid; 249 EXPECT_EQ(pthread_create(&tid, nullptr, ThreadPthreadMtimedlockNoOut, (void*)&mtx), 0) << "> return errno"; 250 251 EXPECT_EQ(pthread_mutex_lock(&mtx), 0) << "> return errno"; 252 Msleep(50); 253 CheckStep(2); 254 EXPECT_EQ(pthread_mutex_unlock(&mtx), 0) << "> return errno"; 255 256 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno"; 257 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 258} 259 260/********************************************* Test case dividing line ***********************************************/ 261 262/** 263 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0100 264 * @tc.name test pthread_mutexattr_init api 265 * @tc.desc [C- SOFTWARE -0200] 266 */ 267HWTEST_F(FutexTest, testPthreadMattrType, Function | MediumTest | Level1) 268{ 269 int type; 270 pthread_mutexattr_t mutexTypeAttr; 271 int errorType = 100; 272 273 EXPECT_EQ(pthread_mutexattr_init(&mutexTypeAttr), 0); 274 275 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_DEFAULT), 0) << "> return errno"; 276 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0); 277 EXPECT_EQ(type, PTHREAD_MUTEX_DEFAULT); 278 279 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_NORMAL), 0) << "> return errno"; 280 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0); 281 EXPECT_EQ(type, PTHREAD_MUTEX_NORMAL); 282 283 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_RECURSIVE), 0) << "> return errno"; 284 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0); 285 EXPECT_EQ(type, PTHREAD_MUTEX_RECURSIVE); 286 287 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, PTHREAD_MUTEX_ERRORCHECK), 0) << "> return errno"; 288 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0); 289 EXPECT_EQ(type, PTHREAD_MUTEX_ERRORCHECK); 290 291 EXPECT_EQ(pthread_mutexattr_settype(&mutexTypeAttr, errorType), EINVAL) << "> return errno"; 292 EXPECT_EQ(pthread_mutexattr_gettype(&mutexTypeAttr, &type), 0); 293 EXPECT_NE(type, errorType); 294} 295 296/********************************************* Test case dividing line ***********************************************/ 297 298void *ThreadMattrTypeRecursive1(void *arg) 299{ 300 pthread_mutex_t *mtx = (pthread_mutex_t *)arg; 301 ChildAssertEQ(pthread_mutex_lock(mtx), 0); 302 Msleep(30); 303 ChildAssertEQ(pthread_mutex_unlock(mtx), 0); 304 return arg; 305} 306 307/** 308 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0200 309 * @tc.name type is PTHREAD_MUTEX_RECURSIVE, unlock when not in use 310 * @tc.desc [C- SOFTWARE -0200] 311 */ 312HWTEST_F(FutexTest, testPthreadMattrTypeRecursive1, Function | MediumTest | Level2) 313{ 314 pid_t pid = fork(); 315 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno; 316 if (pid == 0) { 317 int exitCode = 0; 318 int type; 319 pthread_t tid; 320 pthread_mutex_t mtx; 321 pthread_mutexattr_t mtxTypeAttr; 322 323 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0); 324 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_RECURSIVE), 0); 325 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0); 326 ChildAssertEQ(type, PTHREAD_MUTEX_RECURSIVE); 327 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0); 328 ChildAssertEQ(pthread_create(&tid, nullptr, ThreadMattrTypeRecursive1, (void*)&mtx), 0); 329 Msleep(10); 330 exitCode = ChildExpectEQ(pthread_mutex_unlock(&mtx), EPERM); 331 ChildAssertEQ(pthread_join(tid, nullptr), 0); 332 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0); 333 exit(exitCode); 334 } 335 Msleep(80); 336 WaitProcExitedOK(pid); 337} 338 339/********************************************* Test case dividing line ***********************************************/ 340 341/** 342 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0300 343 * @tc.name type is PTHREAD_MUTEX_RECURSIVE, lock when locked 344 * @tc.desc [C- SOFTWARE -0200] 345 */ 346HWTEST_F(FutexTest, testPthreadMattrTypeRecursive2, Function | MediumTest | Level2) 347{ 348 pid_t pid = fork(); 349 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno; 350 if (pid == 0) { 351 int exitCode = 0; 352 int type; 353 pthread_mutex_t mtx; 354 pthread_mutexattr_t mtxTypeAttr; 355 356 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0); 357 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_RECURSIVE), 0); 358 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0); 359 ChildAssertEQ(type, PTHREAD_MUTEX_RECURSIVE); 360 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0); 361 362 ChildAssertEQ(pthread_mutex_lock(&mtx), 0); 363 exitCode = ChildExpectEQ(pthread_mutex_lock(&mtx), 0); 364 ChildAssertEQ(pthread_mutex_unlock(&mtx), 0); 365 366 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0); 367 exit(exitCode); 368 } 369 Msleep(50); 370 AssertProcExitedOK(pid); 371} 372 373/********************************************* Test case dividing line ***********************************************/ 374 375void *ThreadMattrTypeRecursive3(void *arg) 376{ 377 pthread_mutex_t *mtx = (pthread_mutex_t *)arg; 378 ChildAssertEQ(pthread_mutex_lock(mtx), 0); 379 Msleep(30); 380 ChildAssertEQ(pthread_mutex_unlock(mtx), 0); 381 return arg; 382} 383 384/** 385 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0400 386 * @tc.name type is PTHREAD_MUTEX_ERRORCHECK, unlock when not in use 387 * @tc.desc [C- SOFTWARE -0200] 388 */ 389HWTEST_F(FutexTest, testPthreadMattrTypeRecursive3, Function | MediumTest | Level2) 390{ 391 pid_t pid = fork(); 392 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno; 393 if (pid == 0) { 394 int exitCode; 395 int type; 396 pthread_t tid; 397 pthread_mutex_t mtx; 398 pthread_mutexattr_t mtxTypeAttr; 399 400 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0); 401 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_ERRORCHECK), 0); 402 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0); 403 ChildAssertEQ(type, PTHREAD_MUTEX_ERRORCHECK); 404 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0); 405 ChildAssertEQ(pthread_create(&tid, nullptr, ThreadMattrTypeRecursive3, (void*)&mtx), 0); 406 Msleep(10); 407 exitCode = ChildExpectEQ(pthread_mutex_unlock(&mtx), EPERM); 408 ChildAssertEQ(pthread_join(tid, nullptr), 0); 409 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0); 410 exit(exitCode); 411 } 412 Msleep(80); 413 WaitProcExitedOK(pid); 414} 415 416/********************************************* Test case dividing line ***********************************************/ 417 418/** 419 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0500 420 * @tc.name type is PTHREAD_MUTEX_ERRORCHECK, lock when locked 421 * @tc.desc [C- SOFTWARE -0200] 422 */ 423HWTEST_F(FutexTest, testPthreadMattrTypeRecursive4, Function | MediumTest | Level2) 424{ 425 pid_t pid = fork(); 426 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno; 427 if (pid == 0) { 428 int exitCode = 0; 429 int type; 430 pthread_mutex_t mtx; 431 pthread_mutexattr_t mtxTypeAttr; 432 433 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0); 434 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_ERRORCHECK), 0); 435 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0); 436 ChildAssertEQ(type, PTHREAD_MUTEX_ERRORCHECK); 437 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0); 438 439 ChildAssertEQ(pthread_mutex_lock(&mtx), 0); 440 exitCode = ChildExpectEQ(pthread_mutex_lock(&mtx), EDEADLK); 441 ChildAssertEQ(pthread_mutex_unlock(&mtx), 0); 442 443 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0); 444 exit(exitCode); 445 } 446 Msleep(50); 447 AssertProcExitedOK(pid); 448} 449 450/********************************************* Test case dividing line ***********************************************/ 451 452/** 453 * @tc.number SUB_KERNEL_FUTEX_MTYPE_ALL_0600 454 * @tc.name type is PTHREAD_MUTEX_NORMAL, lock when locked 455 * @tc.desc [C- SOFTWARE -0200] 456 */ 457HWTEST_F(FutexTest, testPthreadMattrTypeRecursive5, Function | MediumTest | Level2) 458{ 459 pid_t pid = fork(); 460 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno; 461 if (pid == 0) { 462 int type; 463 pthread_mutex_t mtx; 464 pthread_mutexattr_t mtxTypeAttr; 465 466 LOG("> child pid = %d", getpid()); 467 ChildAssertEQ(pthread_mutexattr_init(&mtxTypeAttr), 0); 468 ChildAssertEQ(pthread_mutexattr_settype(&mtxTypeAttr, PTHREAD_MUTEX_NORMAL), 0); 469 ChildAssertEQ(pthread_mutexattr_gettype(&mtxTypeAttr, &type), 0); 470 ChildAssertEQ(type, PTHREAD_MUTEX_NORMAL); 471 ChildAssertEQ(pthread_mutex_init(&mtx, &mtxTypeAttr), 0); 472 LOG("> lock"); 473 ChildAssertEQ(pthread_mutex_lock(&mtx), 0); 474 475 // if add pthread_mutex_lock Unreachable 476 LOG("> unlock"); 477 ChildAssertEQ(pthread_mutex_unlock(&mtx), 0); 478 ChildAssertEQ(pthread_mutexattr_destroy(&mtxTypeAttr), 0); 479 exit(0); 480 } 481 LOG("> parent pid = %d", getpid()); 482 Msleep(50); 483 WaitProcExitedOK(pid); 484} 485 486/********************************************* Test case dividing line ***********************************************/ 487 488void *ThreadSpinlock(void *arg) 489{ 490 pthread_spinlock_t *spinLock = (pthread_spinlock_t *)arg; 491 EXPECT_EQ(pthread_spin_lock(spinLock), 0) << "> return errno"; 492 CheckStep(1); 493 Msleep(10); 494 EXPECT_EQ(CheckStep(2), (uint64_t)0x12); 495 EXPECT_EQ(pthread_spin_unlock(spinLock), 0) << "> return errno"; 496 return arg; 497} 498 499/** 500 * @tc.number SUB_KERNEL_FUTEX_SPINLOCK_ALL_0100 501 * @tc.name basic test of pthread_spin_lock 502 * @tc.desc [C- SOFTWARE -0200] 503 */ 504HWTEST_F(FutexTest, testPthreadSpinlock, Function | MediumTest | Level3) 505{ 506 pthread_spinlock_t spinLock; 507 const int loopNum = 5; 508 pthread_t tid[loopNum]; 509 510 EXPECT_EQ(pthread_spin_init(&spinLock, 0), 0); 511 512 for (int i = 0; i < loopNum; i++) { 513 EXPECT_EQ(pthread_create(&tid[i], nullptr, ThreadSpinlock, (void*)&spinLock), 0) << "> return errno"; 514 } 515 for (int i = 0; i < loopNum; i++) { 516 EXPECT_EQ(pthread_join(tid[i], nullptr), 0) << "> return errno"; 517 } 518 EXPECT_EQ(pthread_spin_destroy(&spinLock), 0); 519} 520 521/********************************************* Test case dividing line ***********************************************/ 522 523void *ThreadSpinTrylock1(void *arg) 524{ 525 pthread_spinlock_t *spinLock = (pthread_spinlock_t *)arg; 526 EXPECT_EQ(pthread_spin_trylock(spinLock), 0) << "> return errno"; 527 CheckStep(1); 528 Msleep(50); 529 CheckStep(4); 530 EXPECT_EQ(pthread_spin_unlock(spinLock), 0) << "> return errno"; 531 CheckStep(5); 532 return arg; 533} 534 535void *ThreadSpinTrylock2(void *arg) 536{ 537 Msleep(20); 538 pthread_spinlock_t *spinLock = (pthread_spinlock_t *)arg; 539 CheckStep(2); 540 EXPECT_EQ(pthread_spin_trylock(spinLock), EBUSY) << "> should return errno"; 541 CheckStep(3); 542 return arg; 543} 544 545/** 546 * @tc.number SUB_KERNEL_FUTEX_SPINLOCK_ALL_0200 547 * @tc.name basic test of pthread_spin_trylock 548 * @tc.desc [C- SOFTWARE -0200] 549 */ 550HWTEST_F(FutexTest, testPthreadSpinTrylock, Function | MediumTest | Level3) 551{ 552 pthread_t tid[2]; 553 pthread_spinlock_t spinLock; 554 555 EXPECT_EQ(pthread_spin_init(&spinLock, 0), 0) << "> return errno"; 556 EXPECT_EQ(pthread_create(&tid[0], nullptr, ThreadSpinTrylock1, (void*)&spinLock), 0) << "> return errno"; 557 EXPECT_EQ(pthread_create(&tid[1], nullptr, ThreadSpinTrylock2, (void*)&spinLock), 0) << "> return errno"; 558 559 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 560 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 561 562 EXPECT_EQ(pthread_spin_destroy(&spinLock), 0); 563 EXPECT_EQ(pthread_spin_trylock(&spinLock), 0) << "> return errno"; 564 EXPECT_EQ(CheckStep(6), (uint64_t)0x123456); 565} 566