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#include <stdio.h> 16#include <string.h> 17#include <limits.h> 18#include <pthread.h> 19#include <gtest/gtest.h> 20#include "utils.h" 21#include "log.h" 22#include "KernelConstants.h" 23#include "PthreadTest.h" 24#include "mt_utils.h" 25 26using namespace testing::ext; 27 28void *ThreadPthreadCreateBasic(void *arg) 29{ 30 char *s = (char*)arg; 31 EXPECT_STREQ(s, "1234567890 !@#$%^&*()_= ZXCVBNM [];'./>?:\" +-*/qwertyuiopasdfghjklzxcvbnm"); 32 return arg; 33} 34 35/** 36 * @tc.number SUB_KERNEL_PTHREAD_CREATE_0100 37 * @tc.name pthread_create create a thread 38 * @tc.desc [C- SOFTWARE -0200] 39 */ 40HWTEST_F(PthreadTest, testPthreadCreateBasic, Function | MediumTest | Level2) 41{ 42 pthread_t tid; 43 char str[] = "1234567890 !@#$%^&*()_= ZXCVBNM [];'./>?:\" +-*/qwertyuiopasdfghjklzxcvbnm"; 44 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadCreateBasic, (void*)str), 0) << "> return errno"; 45 46 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno"; 47} 48 49void *ThreadPthreadJoinWait(void *arg) 50{ 51 Msleep(20); 52 CheckStep(2); 53 return arg; 54} 55 56/** 57 * @tc.number SUB_KERNEL_PTHREAD_JOIN_0100 58 * @tc.name Test the waiting function of pthread_join 59 * @tc.desc [C- SOFTWARE -0200] 60 */ 61HWTEST_F(PthreadTest, testPthreadJoinWait, Function | MediumTest | Level2) 62{ 63 pthread_t tid; 64 CheckStep(1); 65 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadJoinWait, nullptr), 0) << "> return errno"; 66 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno"; 67 EXPECT_EQ(CheckStep(3), (uint64_t)0x123) << "pthread_join no wait"; 68} 69 70/** 71 * @tc.number SUB_KERNEL_PTHREAD_JOIN_0200 72 * @tc.name Test the function of pthread_join to get the return value 73 * @tc.desc [C- SOFTWARE -0200] 74 */ 75HWTEST_F(PthreadTest, testJoinReturn, Function | MediumTest | Level3) 76{ 77 pthread_t tid; 78 int num = 4; 79 void *joinRe = nullptr; 80 81 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPublic, (void*)&num), 0) << "> return errno"; 82 EXPECT_EQ(pthread_join(tid, &joinRe), 0) << "> return errno"; 83 84 int *p = (int*)joinRe; 85 EXPECT_TRUE(&num == p); 86} 87 88/** 89 * @tc.number SUB_KERNEL_PTHREAD_JOIN_0300 90 * @tc.name Test the function about pthread_join, but child thread Exited 91 * @tc.desc [C- SOFTWARE -0200] 92 */ 93HWTEST_F(PthreadTest, testJoinExited, Function | MediumTest | Level3) 94{ 95 pthread_t tid; 96 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPublic, nullptr), 0) << "> return errno"; 97 Msleep(50); 98 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno"; 99} 100 101void *ThreadPthreadExitThread(void *arg) 102{ 103 pthread_exit(arg); 104 return nullptr; 105} 106 107/** 108 * @tc.number SUB_KERNEL_PTHREAD_EXIT_0100 109 * @tc.name Test the return function of pthread_exit in the child thread 110 * @tc.desc [C- SOFTWARE -0200] 111 */ 112HWTEST_F(PthreadTest, testPthreadExitThread, Function | MediumTest | Level3) 113{ 114 pthread_t tid; 115 int num = 4; 116 void *joinRe = nullptr; 117 118 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadExitThread, (void*)&num), 0) << "> return errno"; 119 EXPECT_EQ(pthread_join(tid, &joinRe), 0) << "> return errno"; 120 int *p = (int*)joinRe; 121 EXPECT_TRUE(&num == p); 122} 123 124void FunPthreadExit(void *arg) 125{ 126 pthread_exit(arg); 127} 128 129void *ThreadPthreadExitFunction(void *arg) 130{ 131 FunPthreadExit(arg); 132 return nullptr; 133} 134 135/** 136 * @tc.number SUB_KERNEL_PTHREAD_EXIT_0200 137 * @tc.name Test the return function of pthread_exit in the child thread function 138 * @tc.desc [C- SOFTWARE -0200] 139 */ 140HWTEST_F(PthreadTest, testPthreadExitFunction, Function | MediumTest | Level3) 141{ 142 pthread_t tid; 143 int num = 4; 144 void *joinRe = nullptr; 145 146 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadExitFunction, (void*)&num), 0) << "> return errno"; 147 EXPECT_EQ(pthread_join(tid, &joinRe), 0) << "> return errno"; 148 int *p = (int*)joinRe; 149 EXPECT_TRUE(&num == p); 150} 151 152/** 153 * @tc.number SUB_KERNEL_PTHREAD_DETACH_0100 154 * @tc.name Use pthread_detach to detach child threads 155 * @tc.desc [C- SOFTWARE -0200] 156 */ 157HWTEST_F(PthreadTest, testPthreadDetach, Function | MediumTest | Level3) 158{ 159 pthread_t tid; 160 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPublic, nullptr), 0) << "> return errno"; 161 EXPECT_EQ(pthread_detach(tid), 0) << "> return errno"; 162 EXPECT_EQ(pthread_join(tid, nullptr), EINVAL) << "> return errno"; 163} 164 165void *ThreadPthreadEqual(void *arg) 166{ 167 pthread_t *tid = (pthread_t*)arg; 168 EXPECT_NE(pthread_equal(*tid, pthread_self()), 0) << "pthread_equal should be equal"; 169 Msleep(10); 170 return arg; 171} 172 173/** 174 * @tc.number SUB_KERNEL_PTHREAD_EQUAL_0100 175 * @tc.name Use pthread_equal checks process equality 176 * @tc.desc [C- SOFTWARE -0200] 177 */ 178HWTEST_F(PthreadTest, testPthreadEqual, Function | MediumTest | Level3) 179{ 180 pthread_t tid; 181 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadEqual, (void*)&tid), 0) << "> return errno"; 182 EXPECT_EQ(pthread_equal(tid, pthread_self()), 0) << "pthread_equal should be no equal"; 183 EXPECT_EQ(pthread_join(tid, nullptr), 0) << "> return errno"; 184} 185 186/** 187 * @tc.number SUB_KERNEL_PTHREAD_KEY_CREATE_0100 188 * @tc.name Check the parameter PTHREAD_KEYS_MAX of pthread_key_create 189 * @tc.desc [C- SOFTWARE -0200] 190 */ 191HWTEST_F(PthreadTest, testPthreadKeysMax, Function | MediumTest | Level3) 192{ 193 int creatCnt = -1; 194 pid_t pid = fork(); 195 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno; 196 if (pid == 0) { 197 int re; 198 int exitCode = 0; 199 pthread_key_t keys[PTHREAD_KEYS_MAX]; 200 for (int i = 0; i < PTHREAD_KEYS_MAX; i++) { 201 re = pthread_key_create(&keys[i], nullptr); 202 if (re == EAGAIN) { 203 LOG("pthread_key_create %d errno = %d", i, re); 204 creatCnt = i; 205 break; 206 } else if (re != 0) { 207 LOG("pthread_key_create %d errno = %d", i, re); 208 exitCode = 1; 209 creatCnt = i; 210 break; 211 } 212 } 213 214 if (creatCnt == -1) { 215 creatCnt = PTHREAD_KEYS_MAX; 216 } 217 218 for (int i = 0; i < creatCnt; i++) { 219 re = pthread_key_delete(keys[i]); 220 if (re != 0) { 221 LOG("pthread_key_delete %d errno = %d", i, re); 222 exitCode = 1; 223 break; 224 } 225 } 226 exit(exitCode); 227 } 228 WaitProcExitedOK(pid); 229} 230 231/** 232 * @tc.number SUB_KERNEL_PTHREAD_GETSPECIFIC_0100 233 * @tc.name Use pthread_getspecific to get the value corresponding to the parameter key 234 * @tc.desc [C- SOFTWARE -0200] 235 */ 236HWTEST_F(PthreadTest, testPthreadGetspecific, Function | MediumTest | Level3) 237{ 238 pthread_key_t keys; 239 int testInt = 100; 240 void *testVoidP = (void*)&testInt; 241 EXPECT_EQ(pthread_key_create(&keys, nullptr), 0) << "> return errno"; 242 243 void *reVoidP = pthread_getspecific(keys); 244 EXPECT_EQ(reVoidP, nullptr); 245 246 EXPECT_EQ(pthread_setspecific(keys, testVoidP), 0) << "> return errno"; 247 248 reVoidP = pthread_getspecific(keys); 249 EXPECT_EQ(reVoidP, testVoidP); 250 251 EXPECT_EQ(pthread_key_delete(keys), 0) << "> return errno"; 252 253 reVoidP = pthread_getspecific(keys); 254 EXPECT_EQ(reVoidP, nullptr); 255} 256 257pthread_key_t g_keys; 258pthread_once_t g_once = PTHREAD_ONCE_INIT; 259int g_intPthreadSpecificAll = 0; 260 261// Destructor function, excute after ThreadPthreadSpecificAll 262void DestructorPthreadSpecificAll(void *param) 263{ 264 int *p = (int*)param; 265 *p += 1; 266} 267 268void OnceFunc() 269{ 270 // DestructorPthreadSpecificAll() execute twice 271 EXPECT_EQ(pthread_key_create(&g_keys, DestructorPthreadSpecificAll), 0) << "> return errno"; 272 EXPECT_EQ(pthread_getspecific(g_keys), nullptr); 273 // execute once 274 g_intPthreadSpecificAll++; 275 EXPECT_EQ(g_intPthreadSpecificAll, 1); 276} 277 278void *ThreadPthreadSpecificAll(void *arg) 279{ 280 // OnceFunc() execute once 281 int reInt = pthread_once(&g_once, OnceFunc); 282 EXPECT_TRUE((reInt == 0) || (reInt == 2)); 283 284 if (pthread_getspecific(g_keys) == nullptr) { 285 // execute twice 286 g_intPthreadSpecificAll++; 287 EXPECT_EQ(pthread_setspecific(g_keys, (void*)&g_intPthreadSpecificAll), 0) << "> return errno"; 288 } 289 // only 2 or 4 290 EXPECT_GE(g_intPthreadSpecificAll, 2); 291 EXPECT_NE(g_intPthreadSpecificAll, 3); 292 EXPECT_LE(g_intPthreadSpecificAll, 4); 293 return arg; 294} 295 296void DestructorPthreadSpecificAllDelete(void *param) 297{ 298 int *p = (int*)param; 299 *p += 1; 300} 301 302void *ThreadPthreadSpecificAllDelete(void *arg) 303{ 304 pthread_key_t keys; 305 EXPECT_EQ(pthread_key_create(&keys, DestructorPthreadSpecificAllDelete), 0) << "> return errno"; 306 EXPECT_EQ(pthread_getspecific(keys), nullptr); 307 EXPECT_EQ(pthread_setspecific(keys, arg), 0) << "> return errno"; 308 EXPECT_EQ(pthread_getspecific(keys), arg); 309 EXPECT_EQ(pthread_key_delete(keys), 0) << "> return errno"; 310 return arg; 311} 312 313/** 314 * @tc.number SUB_KERNEL_PTHREAD_SPECIFIC_ALL_0200 315 * @tc.name Delete the key before the child thread exits 316 * @tc.desc [C- SOFTWARE -0200] 317 */ 318HWTEST_F(PthreadTest, testPthreadSpecificAllDelete, Function | MediumTest | Level3) 319{ 320 int data = 1; 321 pthread_t tid; 322 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadSpecificAllDelete, (void*)&data), 0) << "> return errno"; 323 Msleep(100); 324 pthread_join(tid, nullptr); 325 EXPECT_EQ(data, 1); 326} 327 328void TestPushHandler1(void *arg) 329{ 330 CheckStep(3); 331} 332 333void TestPushHandler2(void *arg) 334{ 335 CheckStep(2); 336} 337 338void *ThreadTestPush(void *arg) 339{ 340 pthread_cleanup_push(TestPushHandler1, nullptr); 341 pthread_cleanup_push(TestPushHandler2, nullptr); 342 pthread_cleanup_pop(1); 343 pthread_cleanup_pop(1); 344 return arg; 345} 346 347/** 348 * @tc.number SUB_KERNEL_PTHREAD_CLEANUP_ALL_0100 349 * @tc.name pthread_cleanup_push and pthread_cleanup_pop basic test 350 * @tc.desc [C- SOFTWARE -0200] 351 */ 352HWTEST_F(PthreadTest, testPthreadCleanupPushPopBasic, Function | MediumTest | Level3) 353{ 354 pthread_t tid; 355 CheckStep(1); 356 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadTestPush, nullptr), 0) << "> return errno"; 357 Msleep(100); 358 pthread_join(tid, nullptr); 359 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 360} 361 362void TestPushParamHandler(void *arg) 363{ 364 int *testInt = (int*)arg; 365 EXPECT_EQ(*testInt, 1); 366 CheckStep(2); 367} 368 369void *ThreadTestPushParam(void *arg) 370{ 371 int testInt = 1; 372 pthread_cleanup_push(TestPushParamHandler, (void*)&testInt); 373 pthread_cleanup_pop(1); 374 return arg; 375} 376 377/** 378 * @tc.number SUB_KERNEL_PTHREAD_CLEANUP_ALL_0200 379 * @tc.name pthread_cleanup_push and pthread_cleanup_pop test with param 380 * @tc.desc [C- SOFTWARE -0200] 381 */ 382HWTEST_F(PthreadTest, testPthreadCleanupPushPopParam, Function | MediumTest | Level3) 383{ 384 pthread_t tid; 385 CheckStep(1); 386 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadTestPushParam, nullptr), 0) << "> return errno"; 387 Msleep(100); 388 pthread_join(tid, nullptr); 389 EXPECT_EQ(CheckStep(3), (uint64_t)0x123); 390} 391 392void TestPopHandler1(void *arg) 393{ 394 CheckStep(2); 395} 396 397void TestPopHandler2(void *arg) 398{ 399 // unreachable 400 LOG("step = %lx", CheckStep(10)); 401} 402 403static void *ThreadTestop(void *arg) 404{ 405 pthread_cleanup_push(TestPopHandler1, nullptr); 406 pthread_cleanup_push(TestPopHandler2, nullptr); 407 pthread_cleanup_pop(0); 408 pthread_cleanup_pop(1); 409 return arg; 410} 411 412/** 413 * @tc.number SUB_KERNEL_PTHREAD_CLEANUP_ALL_0300 414 * @tc.name pthread_cleanup_pop use different parameters 415 * @tc.desc [C- SOFTWARE -0200] 416 */ 417HWTEST_F(PthreadTest, testPop, Function | MediumTest | Level3) 418{ 419 pthread_t tid; 420 CheckStep(1); 421 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadTestop, nullptr), 0) << "> return errno"; 422 Msleep(100); 423 pthread_join(tid, nullptr); 424 EXPECT_EQ(CheckStep(3), (uint64_t)0x123); 425} 426 427/** 428 * @tc.number SUB_KERNEL_PTHREAD_BARRIER_INIT_0100 429 * @tc.name basic test of pthread_barrier_init 430 * @tc.desc [C- SOFTWARE -0200] 431 */ 432HWTEST_F(PthreadTest, testBarrierInit, Function | MediumTest | Level2) 433{ 434 pthread_barrier_t barrier; 435 EXPECT_EQ(pthread_barrier_init(&barrier, nullptr, 0), EINVAL) << "> return errno"; 436} 437 438/** 439 * @tc.number SUB_KERNEL_PTHREAD_BARRIERATTR_INIT_0100 440 * @tc.name basic test with pthread_barrierattr_init 441 * @tc.desc [C- SOFTWARE -0200] 442 */ 443HWTEST_F(PthreadTest, testBarrierattrInit, Function | MediumTest | Level3) 444{ 445 pthread_barrierattr_t barrierAttr; 446 pthread_barrier_t barrier; 447 EXPECT_EQ(pthread_barrierattr_init(&barrierAttr), 0); 448 EXPECT_EQ(pthread_barrierattr_destroy(&barrierAttr), 0); 449 EXPECT_EQ(pthread_barrier_init(&barrier, &barrierAttr, 1), 0) << "> return errno"; 450 EXPECT_EQ(pthread_barrier_destroy(&barrier), 0) << "> return errno"; 451} 452 453static pthread_barrier_t g_barrier; 454void *ThreadTestBarrierWait1(void *arg) 455{ 456 int *intP = (int*)arg; 457 int reInt = pthread_barrier_wait(&g_barrier); 458 if (reInt == PTHREAD_BARRIER_SERIAL_THREAD) { 459 CheckStep(2); 460 } else if (reInt == 0) { 461 Msleep(30); 462 *intP += 1; 463 } else { 464 ADD_FAILURE(); 465 } 466 return arg; 467} 468 469void *ThreadTestBarrierWait2(void *arg) 470{ 471 int *intP = (int*)arg; 472 int reInt = pthread_barrier_wait(&g_barrier); 473 if (reInt == PTHREAD_BARRIER_SERIAL_THREAD) { 474 CheckStep(2); 475 } else if (reInt == 0) { 476 Msleep(20); 477 *intP += 1; 478 } else { 479 ADD_FAILURE(); 480 } 481 return arg; 482} 483 484/** 485 * @tc.number SUB_KERNEL_PTHREAD_BARRIER_ALL_0100 486 * @tc.name test pthread_barrier_wait return value 487 * @tc.desc [C- SOFTWARE -0200] 488 */ 489HWTEST_F(PthreadTest, testBarrierWait, Function | MediumTest | Level3) 490{ 491 pthread_t tid; 492 pthread_t tid1; 493 CheckStep(1); 494 int intParam = 0; 495 496 EXPECT_EQ(pthread_barrier_init(&g_barrier, nullptr, 3), 0) << "> return errno"; 497 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadTestBarrierWait1, (void*)&intParam), 0) << "> return errno"; 498 ASSERT_EQ(pthread_create(&tid1, nullptr, ThreadTestBarrierWait2, (void*)&intParam), 0) << "> return errno"; 499 int reInt = pthread_barrier_wait(&g_barrier); 500 if (reInt == PTHREAD_BARRIER_SERIAL_THREAD) { 501 CheckStep(2); 502 } else if (reInt == 0) { 503 Msleep(10); 504 intParam++; 505 } else { 506 ADD_FAILURE(); 507 } 508 Msleep(50); 509 pthread_join(tid, nullptr); 510 pthread_join(tid1, nullptr); 511 EXPECT_EQ(pthread_barrier_destroy(&g_barrier), 0) << "> return errno"; 512 EXPECT_EQ(CheckStep(3), (uint64_t)0x123); 513 EXPECT_EQ(intParam, 2); 514} 515 516void *ThreadTestBarrierAlwaysWait(void *arg) 517{ 518 pthread_barrier_t *barrier = (pthread_barrier_t*)arg; 519 int reInt = pthread_barrier_wait(barrier); 520 if ((reInt != PTHREAD_BARRIER_SERIAL_THREAD) && (reInt != 0)) { 521 ADD_FAILURE(); 522 } 523 CheckStep(3); 524 return arg; 525} 526 527/** 528 * @tc.number SUB_KERNEL_PTHREAD_BARRIER_ALL_0200 529 * @tc.name Comprehensive test with barrier properties, always waiting 530 * @tc.desc [C- SOFTWARE -0200] 531 */ 532HWTEST_F(PthreadTest, testBarrierAlwaysWait, Function | MediumTest | Level3) 533{ 534 pthread_t tid; 535 pthread_t tid1; 536 pthread_barrier_t barrier; 537 CheckStep(1); 538 539 EXPECT_EQ(pthread_barrier_init(&barrier, nullptr, 3), 0) << "> return errno"; 540 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadTestBarrierAlwaysWait, (pthread_barrier_t*)&barrier), 0) 541 << "> return errno"; 542 ASSERT_EQ(pthread_create(&tid1, nullptr, ThreadTestBarrierAlwaysWait, (pthread_barrier_t*)&barrier), 0) 543 << "> return errno"; 544 545 Msleep(100); 546 EXPECT_EQ(CheckStep(2), (uint64_t)0x12); // childs threads always waiting 547 int reInt = pthread_barrier_wait(&barrier); 548 if ((reInt != PTHREAD_BARRIER_SERIAL_THREAD) && (reInt != 0)) { 549 ADD_FAILURE(); 550 } 551 pthread_join(tid, nullptr); 552 pthread_join(tid1, nullptr); 553 EXPECT_EQ(pthread_barrier_destroy(&barrier), 0) << "> return errno"; 554} 555 556/** 557 * @tc.number SUB_KERNEL_PTHREAD_SETCANCELSTATE_0100 558 * @tc.name basic test about pthread_setcancelstate 559 * @tc.desc [C- SOFTWARE -0200] 560 */ 561HWTEST_F(PthreadTest, testPthreadSetcancelstate, Function | MediumTest | Level3) 562{ 563 int oldState = 0; 564 EXPECT_EQ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState), 0) << "> return errno"; 565 EXPECT_EQ(oldState, PTHREAD_CANCEL_ENABLE); 566 EXPECT_EQ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldState), 0) << "> return errno"; 567 EXPECT_EQ(oldState, PTHREAD_CANCEL_DISABLE); 568 EXPECT_EQ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr), 0) << "> return errno"; 569 EXPECT_EQ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr), 0) << "> return errno"; 570} 571 572/** 573 * @tc.number SUB_KERNEL_PTHREAD_SETCANCELTYPE_0100 574 * @tc.name basic test about pthread_setcanceltype 575 * @tc.desc [C- SOFTWARE -0200] 576 */ 577HWTEST_F(PthreadTest, testPthreadSetcanceltype, Function | MediumTest | Level3) 578{ 579 int oldState = 0; 580 EXPECT_EQ(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldState), 0) << "> return errno"; 581 EXPECT_EQ(oldState, PTHREAD_CANCEL_DEFERRED); 582 EXPECT_EQ(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldState), 0) << "> return errno"; 583 EXPECT_EQ(oldState, PTHREAD_CANCEL_ASYNCHRONOUS); 584 EXPECT_EQ(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr), 0) << "> return errno"; 585 EXPECT_EQ(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, nullptr), 0) << "> return errno"; 586} 587 588void *ThreadPthreadNoCancelPoint(void *arg) 589{ 590 CheckStep(2); 591 KeepRun(50); 592 CheckStep(3); 593 return arg; 594} 595 596/** 597 * @tc.number SUB_KERNEL_PTHREAD_CANCEL_0100 598 * @tc.name test pthread_cancel with no cancel point 599 * @tc.desc [C- SOFTWARE -0200] 600 */ 601HWTEST_F(PthreadTest, testPthreadNoCancelPoint, Function | MediumTest | Level3) 602{ 603 pthread_t tid; 604 CheckStep(1); 605 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadNoCancelPoint, nullptr), 0) << "> return errno"; 606 Msleep(10); 607 EXPECT_EQ(pthread_cancel(tid), 0); 608 Msleep(100); 609 EXPECT_EQ(pthread_join(tid, NULL), 0); 610} 611 612void *ThreadPthreadCancelPoint(void *arg) 613{ 614 CheckStep(2); 615 KeepRun(50); 616 pthread_testcancel(); 617 618 // unreachable 619 CheckStep(3); 620 return arg; 621} 622 623/** 624 * @tc.number SUB_KERNEL_PTHREAD_CANCEL_0200 625 * @tc.name test pthread_cancel with cancel point 626 * @tc.desc [C- SOFTWARE -0200] 627 */ 628HWTEST_F(PthreadTest, testPthreadCancelPoint, Function | MediumTest | Level3) 629{ 630 pthread_t tid; 631 CheckStep(1); 632 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadCancelPoint, nullptr), 0) << "> return errno"; 633 Msleep(20); 634 EXPECT_EQ(pthread_cancel(tid), 0); 635 Msleep(100); 636 EXPECT_EQ(pthread_join(tid, NULL), 0); 637 EXPECT_EQ(CheckStep(3), (uint64_t)0x123); 638} 639 640void *ThreadPthreadCancelDisable(void *arg) 641{ 642 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr); 643 CheckStep(2); 644 Msleep(50); 645 pthread_testcancel(); 646 CheckStep(3); 647 return arg; 648} 649 650/** 651 * @tc.number SUB_KERNEL_PTHREAD_CANCEL_ALL_0100 652 * @tc.name test pthread_cancel with PTHREAD_CANCEL_DISABLE 653 * @tc.desc [C- SOFTWARE -0200] 654 */ 655HWTEST_F(PthreadTest, testPthreadCancelDisable, Function | MediumTest | Level3) 656{ 657 pthread_t tid; 658 CheckStep(1); 659 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadCancelDisable, nullptr), 0) << "> return errno"; 660 Msleep(10); 661 EXPECT_EQ(pthread_cancel(tid), 0); 662 Msleep(100); 663 EXPECT_EQ(pthread_join(tid, NULL), 0); 664 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 665} 666 667void *ThreadPthreadCancelAsynchronous(void *arg) 668{ 669 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); 670 CheckStep(2); 671 KeepRun(50); 672 673 // unreachable 674 CheckStep(3); 675 return arg; 676} 677 678/** 679 * @tc.number SUB_KERNEL_PTHREAD_CANCEL_ALL_0200 680 * @tc.name test pthread_cancel with PTHREAD_CANCEL_ASYNCHRONOUS 681 * @tc.desc [C- SOFTWARE -0200] 682 */ 683HWTEST_F(PthreadTest, testPthreadCancelAsynchronous, Function | MediumTest | Level3) 684{ 685 pthread_t tid; 686 CheckStep(1); 687 688 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadCancelAsynchronous, nullptr), 0) << "> return errno"; 689 Msleep(10); 690 EXPECT_EQ(pthread_cancel(tid), 0); 691 Msleep(100); 692 EXPECT_EQ(pthread_join(tid, NULL), 0); 693 EXPECT_EQ(CheckStep(3), (uint64_t)0x123); 694} 695 696void *ThreadPthreadCancelDeferred(void *arg) 697{ 698 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, nullptr); 699 CheckStep(2); 700 KeepRun(50); 701 CheckStep(3); 702 Msleep(100); 703 return arg; 704} 705 706/** 707 * @tc.number SUB_KERNEL_PTHREAD_CANCEL_ALL_0300 708 * @tc.name test pthread_cancel with PTHREAD_CANCEL_DEFERRED 709 * @tc.desc [C- SOFTWARE -0200] 710 */ 711HWTEST_F(PthreadTest, testPthreadCancelDeferred, Function | MediumTest | Level3) 712{ 713 pthread_t tid; 714 CheckStep(1); 715 716 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadCancelDeferred, nullptr), 0) << "> return errno"; 717 Msleep(10); 718 EXPECT_EQ(pthread_cancel(tid), 0); 719 Msleep(100); 720 EXPECT_EQ(pthread_join(tid, NULL), 0); 721 EXPECT_EQ(CheckStep(4), (uint64_t)0x1234); 722} 723 724void *ThreadPthreadCancelEnable(void *arg) 725{ 726 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr); 727 CheckStep(2); 728 Msleep(50); 729 pthread_testcancel(); 730 // unreachable 731 CheckStep(3); 732 return arg; 733} 734 735/** 736 * @tc.number SUB_KERNEL_PTHREAD_CANCEL_ALL_0400 737 * @tc.name test pthread_cancel with PTHREAD_CANCEL_ENABLE 738 * @tc.desc [C- SOFTWARE -0200] 739 */ 740HWTEST_F(PthreadTest, testPthreadCancelEnable, Function | MediumTest | Level3) 741{ 742 pthread_t tid; 743 CheckStep(1); 744 ASSERT_EQ(pthread_create(&tid, nullptr, ThreadPthreadCancelEnable, nullptr), 0) << "> return errno"; 745 Msleep(10); 746 EXPECT_EQ(pthread_cancel(tid), 0); 747 Msleep(100); 748 EXPECT_EQ(pthread_join(tid, NULL), 0); 749 EXPECT_EQ(CheckStep(3), (uint64_t)0x123); 750} 751 752void PreparePthreadAtfork(void) 753{ 754 CheckStep(2); 755} 756 757void ParentPthreadAtfork(void) 758{ 759 Msleep(20); 760 CheckStep(5); 761} 762 763void ChildPthreadAtfork(void) 764{ 765 CheckStep(3); 766} 767 768/** 769 * @tc.number SUB_KERNEL_PTHREAD_ATFORK_0100 770 * @tc.name Basic test about pthread_atfork whit one thread 771 * @tc.desc [C- SOFTWARE -0200] 772 */ 773HWTEST_F(PthreadTest, testPthreadAtfork, Function | MediumTest | Level3) 774{ 775 pid_t pid = fork(); 776 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno; 777 if (pid == 0) { 778 CheckStep(1); 779 if (pthread_atfork(PreparePthreadAtfork, ParentPthreadAtfork, ChildPthreadAtfork) != 0) { 780 exit(1); 781 } 782 783 pid_t pid = fork(); 784 if (pid < 0){ 785 exit(1); 786 } else if (pid == 0) { 787 if (CheckStep(4) != 0x1234) { 788 exit(1); 789 } 790 exit(0); 791 } 792 if (CheckStep(6) != 0x123456) { 793 exit(1); 794 } 795 796 // check child-child exit 797 int exitCode; 798 int procStat = CheckProcStatus(pid, &exitCode, 0); 799 if (procStat != 1) { 800 exit(1); 801 } 802 if (exitCode != 0) { 803 LOG("> target process should exited 0"); 804 exit(1); 805 } 806 exit(0); 807 } 808 WaitProcExitedOK(pid); 809} 810 811void PrepareNPthreadAtfork(void) 812{ 813 CheckStep(2); 814} 815 816void ParentNPthreadAtfork(void) 817{ 818 Msleep(20); 819 CheckStep(5); 820} 821 822void ChildNPthreadAtfork(void) 823{ 824 CheckStep(3); 825} 826 827void *ThreadNPthreadAtfork(void *arg) 828{ 829 CheckStep(1); 830 if (pthread_atfork(PrepareNPthreadAtfork, ParentNPthreadAtfork, ChildNPthreadAtfork) != 0) { 831 exit(1); 832 } 833 pid_t pid = fork(); 834 if (pid < 0) { 835 LOG("> fork errno = %d", errno); 836 exit(1); 837 } else if (pid == 0) { 838 if (CheckStep(4) != 0x1234) { 839 exit(1); 840 } 841 exit(0); 842 } 843 844 if (CheckStep(6) != 0x123456) { 845 exit(1); 846 } 847 // check child-child exit 848 int exitCode; 849 int procStat = CheckProcStatus(pid, &exitCode, 0); 850 if (procStat != 1) { 851 exit(1); 852 } 853 if (exitCode != 0) { 854 LOG("> target process should exited 0"); 855 exit(1); 856 } 857 exit(0); 858 return arg; 859} 860 861/** 862 * @tc.number SUB_KERNEL_PTHREAD_ATFORK_0200 863 * @tc.name Basic test about pthread_atfork whit two thread 864 * @tc.desc [C- SOFTWARE -0200] 865 */ 866HWTEST_F(PthreadTest, testNPthreadAtfork, Function | MediumTest | Level3) 867{ 868 pid_t pid = fork(); 869 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno; 870 if (pid == 0) { 871 pthread_t tid; 872 if (pthread_create(&tid, nullptr, ThreadNPthreadAtfork, nullptr) != 0) { 873 exit(1); 874 } 875 if (pthread_join(tid, nullptr) != 0) { 876 exit(1); 877 } 878 exit(0); 879 } 880 WaitProcExitedOK(pid); 881} 882 883void FunOnce(void) 884{ 885 CheckStep(2); 886} 887 888void *ThreadOnce(void *arg) 889{ 890 pthread_once_t *once = (pthread_once_t*)arg; 891 EXPECT_EQ(pthread_once(once, FunOnce), 0); 892 return arg; 893} 894 895/** 896 * @tc.number SUB_KERNEL_PTHREAD_ONCE_0100 897 * @tc.name pthread_once basic test 898 * @tc.desc [C- SOFTWARE -0200] 899 */ 900HWTEST_F(PthreadTest, testPthreadOnce, Function | MediumTest | Level3) 901{ 902 pthread_once_t once = PTHREAD_ONCE_INIT; 903 pthread_t tid[2]; 904 CheckStep(1); 905 ASSERT_EQ(pthread_create(&tid[0], nullptr, ThreadOnce, (void*)&once), 0) << "> return errno"; 906 ASSERT_EQ(pthread_create(&tid[1], nullptr, ThreadOnce, (void*)&once), 0) << "> return errno"; 907 EXPECT_EQ(pthread_join(tid[0], nullptr), 0) << "> return errno"; 908 EXPECT_EQ(pthread_join(tid[1], nullptr), 0) << "> return errno"; 909 EXPECT_EQ(CheckStep(3), (uint64_t)0x123); 910} 911