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