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
26 using namespace testing::ext;
27
ThreadPthreadCreateBasic(void *arg)28 void *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 */
HWTEST_F(PthreadTest, testPthreadCreateBasic, Function | MediumTest | Level2)40 HWTEST_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
ThreadPthreadJoinWait(void *arg)49 void *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 */
HWTEST_F(PthreadTest, testPthreadJoinWait, Function | MediumTest | Level2)61 HWTEST_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 */
HWTEST_F(PthreadTest, testJoinReturn, Function | MediumTest | Level3)75 HWTEST_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 */
HWTEST_F(PthreadTest, testJoinExited, Function | MediumTest | Level3)93 HWTEST_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
ThreadPthreadExitThread(void *arg)101 void *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 */
HWTEST_F(PthreadTest, testPthreadExitThread, Function | MediumTest | Level3)112 HWTEST_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
FunPthreadExit(void *arg)124 void FunPthreadExit(void *arg)
125 {
126 pthread_exit(arg);
127 }
128
ThreadPthreadExitFunction(void *arg)129 void *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 */
HWTEST_F(PthreadTest, testPthreadExitFunction, Function | MediumTest | Level3)140 HWTEST_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 */
HWTEST_F(PthreadTest, testPthreadDetach, Function | MediumTest | Level3)157 HWTEST_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
ThreadPthreadEqual(void *arg)165 void *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 */
HWTEST_F(PthreadTest, testPthreadEqual, Function | MediumTest | Level3)178 HWTEST_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 */
HWTEST_F(PthreadTest, testPthreadKeysMax, Function | MediumTest | Level3)191 HWTEST_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 */
HWTEST_F(PthreadTest, testPthreadGetspecific, Function | MediumTest | Level3)236 HWTEST_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
257 pthread_key_t g_keys;
258 pthread_once_t g_once = PTHREAD_ONCE_INIT;
259 int g_intPthreadSpecificAll = 0;
260
261 // Destructor function, excute after ThreadPthreadSpecificAll
DestructorPthreadSpecificAll(void *param)262 void DestructorPthreadSpecificAll(void *param)
263 {
264 int *p = (int*)param;
265 *p += 1;
266 }
267
OnceFunc()268 void 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
ThreadPthreadSpecificAll(void *arg)278 void *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
DestructorPthreadSpecificAllDelete(void *param)296 void DestructorPthreadSpecificAllDelete(void *param)
297 {
298 int *p = (int*)param;
299 *p += 1;
300 }
301
ThreadPthreadSpecificAllDelete(void *arg)302 void *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 */
HWTEST_F(PthreadTest, testPthreadSpecificAllDelete, Function | MediumTest | Level3)318 HWTEST_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
TestPushHandler1(void *arg)328 void TestPushHandler1(void *arg)
329 {
330 CheckStep(3);
331 }
332
TestPushHandler2(void *arg)333 void TestPushHandler2(void *arg)
334 {
335 CheckStep(2);
336 }
337
ThreadTestPush(void *arg)338 void *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 */
HWTEST_F(PthreadTest, testPthreadCleanupPushPopBasic, Function | MediumTest | Level3)352 HWTEST_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
TestPushParamHandler(void *arg)362 void TestPushParamHandler(void *arg)
363 {
364 int *testInt = (int*)arg;
365 EXPECT_EQ(*testInt, 1);
366 CheckStep(2);
367 }
368
ThreadTestPushParam(void *arg)369 void *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 */
HWTEST_F(PthreadTest, testPthreadCleanupPushPopParam, Function | MediumTest | Level3)382 HWTEST_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
TestPopHandler1(void *arg)392 void TestPopHandler1(void *arg)
393 {
394 CheckStep(2);
395 }
396
TestPopHandler2(void *arg)397 void TestPopHandler2(void *arg)
398 {
399 // unreachable
400 LOG("step = %lx", CheckStep(10));
401 }
402
ThreadTestop(void *arg)403 static 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 */
HWTEST_F(PthreadTest, testPop, Function | MediumTest | Level3)417 HWTEST_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 */
HWTEST_F(PthreadTest, testBarrierInit, Function | MediumTest | Level2)432 HWTEST_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 */
HWTEST_F(PthreadTest, testBarrierattrInit, Function | MediumTest | Level3)443 HWTEST_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
453 static pthread_barrier_t g_barrier;
ThreadTestBarrierWait1(void *arg)454 void *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
ThreadTestBarrierWait2(void *arg)469 void *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 */
HWTEST_F(PthreadTest, testBarrierWait, Function | MediumTest | Level3)489 HWTEST_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
ThreadTestBarrierAlwaysWait(void *arg)516 void *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 */
HWTEST_F(PthreadTest, testBarrierAlwaysWait, Function | MediumTest | Level3)532 HWTEST_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 */
HWTEST_F(PthreadTest, testPthreadSetcancelstate, Function | MediumTest | Level3)561 HWTEST_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 */
HWTEST_F(PthreadTest, testPthreadSetcanceltype, Function | MediumTest | Level3)577 HWTEST_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
ThreadPthreadNoCancelPoint(void *arg)588 void *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 */
HWTEST_F(PthreadTest, testPthreadNoCancelPoint, Function | MediumTest | Level3)601 HWTEST_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
ThreadPthreadCancelPoint(void *arg)612 void *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 */
HWTEST_F(PthreadTest, testPthreadCancelPoint, Function | MediumTest | Level3)628 HWTEST_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
ThreadPthreadCancelDisable(void *arg)640 void *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 */
HWTEST_F(PthreadTest, testPthreadCancelDisable, Function | MediumTest | Level3)655 HWTEST_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
ThreadPthreadCancelAsynchronous(void *arg)667 void *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 */
HWTEST_F(PthreadTest, testPthreadCancelAsynchronous, Function | MediumTest | Level3)683 HWTEST_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
ThreadPthreadCancelDeferred(void *arg)696 void *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 */
HWTEST_F(PthreadTest, testPthreadCancelDeferred, Function | MediumTest | Level3)711 HWTEST_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
ThreadPthreadCancelEnable(void *arg)724 void *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 */
HWTEST_F(PthreadTest, testPthreadCancelEnable, Function | MediumTest | Level3)740 HWTEST_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
PreparePthreadAtfork(void)752 void PreparePthreadAtfork(void)
753 {
754 CheckStep(2);
755 }
756
ParentPthreadAtfork(void)757 void ParentPthreadAtfork(void)
758 {
759 Msleep(20);
760 CheckStep(5);
761 }
762
ChildPthreadAtfork(void)763 void 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 */
HWTEST_F(PthreadTest, testPthreadAtfork, Function | MediumTest | Level3)773 HWTEST_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
PrepareNPthreadAtfork(void)811 void PrepareNPthreadAtfork(void)
812 {
813 CheckStep(2);
814 }
815
ParentNPthreadAtfork(void)816 void ParentNPthreadAtfork(void)
817 {
818 Msleep(20);
819 CheckStep(5);
820 }
821
ChildNPthreadAtfork(void)822 void ChildNPthreadAtfork(void)
823 {
824 CheckStep(3);
825 }
826
ThreadNPthreadAtfork(void *arg)827 void *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 */
HWTEST_F(PthreadTest, testNPthreadAtfork, Function | MediumTest | Level3)866 HWTEST_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
FunOnce(void)883 void FunOnce(void)
884 {
885 CheckStep(2);
886 }
887
ThreadOnce(void *arg)888 void *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 */
HWTEST_F(PthreadTest, testPthreadOnce, Function | MediumTest | Level3)900 HWTEST_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