• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "ohos_types.h"
33 #include <securec.h>
34 #include "hctest.h"
35 #include "los_config.h"
36 #include "cmsis_os2.h"
37 #include "kernel_test.h"
38 #include "pthread.h"
39 #include "log.h"
40 
41 #define TASK_PRIO_TEST           LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO
42 #define OS_TSK_TEST_STACK_SIZE   0x1000
43 #define PTHREAD_TASK_DELAY       10
44 
45 static INT32 g_pthreadSem = 0;
46 static UINT32 g_testCount;
47 
48 /**
49  * @tc.desc      : register a test suite, this suite is used to test basic flow and interface dependency
50  * @param        : subsystem name is pthread
51  * @param        : module name is pthread
52  * @param        : test suit name is PthreadFuncTestSuite
53  */
54 LITE_TEST_SUIT(Posix, Pthread, PthreadFuncTestSuite);
55 
56 /**
57  * @tc.setup     : setup for all testcases
58  * @return       : setup result, TRUE is success, FALSE is fail
59  */
PthreadFuncTestSuiteSetUp(void)60 static BOOL PthreadFuncTestSuiteSetUp(void)
61 {
62     return TRUE;
63 }
64 
65 /**
66  * @tc.teardown  : teardown for all testcases
67  * @return       : teardown result, TRUE is success, FALSE is fail
68  */
PthreadFuncTestSuiteTearDown(void)69 static BOOL PthreadFuncTestSuiteTearDown(void)
70 {
71     printf("+-------------------------------------------+\n");
72     return TRUE;
73 }
74 
pthread_join_f01(void * argument)75 static VOID *pthread_join_f01(void *argument)
76 {
77     g_testCount++;
78 
79     pthread_exit((void *)8); /* 8: pthread exit code */
80     return (void *)9; /* 9: return val */
81 }
82 
83 /**
84  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_001
85  * @tc.name      : event operation for join
86  * @tc.desc      : [C- SOFTWARE -0200]
87  */
88 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread001, Function | MediumTest | Level1)
89 {
90     pthread_attr_t attr;
91     pthread_t newTh;
92     struct sched_param schedParam = { 0 };
93     UINT32 ret;
94     UINTPTR uwtemp = 1;
95 
96     g_testCount = 0;
97 
98     ret = pthread_attr_init(&attr);
99     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
100 
101     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
102     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
103 
104     schedParam.sched_priority = TASK_PRIO_TEST;
105     ret = pthread_attr_setschedparam(&attr, &schedParam);
106     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
107 
108     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
109     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
110 
111     ret = pthread_create(&newTh, &attr, pthread_join_f01, NULL);
112     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
113 
114     ret = pthread_join(newTh, (void **)&uwtemp);
115     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
116     ICUNIT_ASSERT_EQUAL(uwtemp, 8, uwtemp); /* 8: pthread exit code */
117 
118     return LOS_OK;
119 };
120 
pthread_join_f02(void * argument)121 static VOID *pthread_join_f02(void *argument)
122 {
123     g_testCount++;
124 
125     return (void *)9; /* 9: return val */
126 }
127 
128 /**
129  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_002
130  * @tc.name      : event operation for join
131  * @tc.desc      : [C- SOFTWARE -0200]
132  */
133 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread002, Function | MediumTest | Level1)
134 {
135     pthread_attr_t attr;
136     pthread_t newTh;
137     struct sched_param schedParam = { 0 };
138     UINT32 ret;
139     UINTPTR uwtemp = 1;
140 
141     g_testCount = 0;
142 
143     ret = pthread_attr_init(&attr);
144     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
145 
146     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
147     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
148 
149     schedParam.sched_priority = TASK_PRIO_TEST;
150     ret = pthread_attr_setschedparam(&attr, &schedParam);
151     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
152 
153     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
154     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
155 
156     ret = pthread_create(&newTh, &attr, pthread_join_f02, NULL);
157     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
158 
159     ret = pthread_join(newTh, (void **)&uwtemp);
160     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
161     ICUNIT_ASSERT_EQUAL(uwtemp, 9, uwtemp); /* 9: pthread exit code */
162 
163     return LOS_OK;
164 };
165 
pthread_join_f03(void * argument)166 static VOID *pthread_join_f03(void *argument)
167 {
168     int ret = pthread_detach(pthread_self());
169     ICUNIT_GOTO_EQUAL(ret, ESRCH, ret, EXIT);
170 
171     g_testCount++;
172 EXIT:
173     return NULL;
174 }
175 
176 /**
177  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_003
178  * @tc.name      : event operation for deatch
179  * @tc.desc      : [C- SOFTWARE -0200]
180  */
181 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread003, Function | MediumTest | Level1)
182 {
183     pthread_attr_t attr;
184     pthread_t newTh;
185     struct sched_param schedParam = { 0 };
186     UINT32 ret;
187 
188     g_testCount = 0;
189 
190     ret = pthread_attr_init(&attr);
191     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
192 
193     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
194     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
195 
196     schedParam.sched_priority = TASK_PRIO_TEST + 1;
197     ret = pthread_attr_setschedparam(&attr, &schedParam);
198     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
199 
200     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
201     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
202 
203     ret = pthread_create(&newTh, &attr, pthread_join_f03, NULL);
204     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
205 
206     ret = pthread_join(newTh, NULL);
207     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
208 
209     ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
210     return LOS_OK;
211 };
212 
pthread_join_f04(void * argument)213 static VOID *pthread_join_f04(void *argument)
214 {
215     int ret = pthread_detach(pthread_self());
216     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
217 
218     g_testCount++;
219 EXIT:
220     return NULL;
221 }
222 
223 /**
224  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_004
225  * @tc.name      : event operation for deatch
226  * @tc.desc      : [C- SOFTWARE -0200]
227  */
228 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread004, Function | MediumTest | Level1)
229 {
230     pthread_attr_t attr;
231     pthread_t newTh;
232     struct sched_param schedParam = { 0 };
233     UINT32 ret;
234 
235     g_testCount = 0;
236 
237     ret = pthread_attr_init(&attr);
238     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
239 
240     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
241     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
242 
243     schedParam.sched_priority = TASK_PRIO_TEST - 1;
244     ret = pthread_attr_setschedparam(&attr, &schedParam);
245     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
246 
247     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
248     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
249 
250     ret = pthread_create(&newTh, &attr, pthread_join_f04, NULL);
251     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
252 
253     ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
254 
255     ret = pthread_join(newTh, NULL);
256     ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret);
257 
258     return LOS_OK;
259 };
260 
pthread_join_f05(void * argument)261 static VOID *pthread_join_f05(void *argument)
262 {
263     int ret = pthread_detach(pthread_self());
264     ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT);
265 
266     usleep(100000); /* 100000: sleep 100 ms */
267 EXIT:
268     return NULL;
269 }
270 
271 /**
272  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_005
273  * @tc.name      : event operation for deatch
274  * @tc.desc      : [C- SOFTWARE -0200]
275  */
276 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread005, Function | MediumTest | Level1)
277 {
278     pthread_attr_t attr;
279     pthread_t newTh;
280     struct sched_param schedParam = { 0 };
281     UINT32 ret;
282 
283     ret = pthread_attr_init(&attr);
284     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
285 
286     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
287     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
288 
289     schedParam.sched_priority = TASK_PRIO_TEST - 1;
290     ret = pthread_attr_setschedparam(&attr, &schedParam);
291     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
292 
293     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
294     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
295 
296     ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
297     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
298 
299     ret = pthread_create(&newTh, &attr, pthread_join_f05, NULL);
300     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
301 
302     ret = pthread_join(newTh, NULL);
303     ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
304 
305     return LOS_OK;
306 };
307 
308 static pthread_cond_t g_pthread_cond;
309 static pthread_mutex_t g_pthread_mutex;
310 #define TEST_THREAD_COUNT 5
pthread_cond_func001(void * arg)311 static void *pthread_cond_func001(void *arg)
312 {
313     int ret;
314     struct timespec ts;
315 
316     g_testCount++;
317 
318     ret = pthread_mutex_lock(&g_pthread_mutex);
319     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
320 
321     clock_gettime(CLOCK_REALTIME, &ts);
322     ts.tv_sec += 60; /* 60: wait 1 minute */
323 
324     ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
325     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
326 
327     ret = pthread_mutex_unlock(&g_pthread_mutex);
328     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
329 
330     g_testCount++;
331 EXIT:
332     return NULL;
333 }
334 
pthread_f06(void * argument)335 static VOID *pthread_f06(void *argument)
336 {
337     int policy;
338     int ret;
339     int i;
340     pthread_attr_t attr;
341     struct sched_param schedParam = { 0 };
342     pthread_t thread[TEST_THREAD_COUNT];
343 
344     g_testCount = 0;
345 
346     ret = pthread_attr_init(&attr);
347     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
348 
349     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
350     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
351 
352     ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
353     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
354 
355     schedParam.sched_priority -= 1;
356     ret = pthread_attr_setschedparam(&attr, &schedParam);
357     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
358 
359     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
360     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
361 
362     for (i = 0; i < TEST_THREAD_COUNT; i++) {
363         ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL);
364         ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
365     }
366 
367     ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
368 
369     ret = pthread_mutex_lock(&g_pthread_mutex);
370     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
371 
372     ret = pthread_cond_broadcast(&g_pthread_cond);
373     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
374 
375     ret = pthread_mutex_unlock(&g_pthread_mutex);
376     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
377 
378     ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
379 
380     for (i = 0; i < TEST_THREAD_COUNT; i++) {
381         ret = pthread_join(thread[i], NULL);
382         ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
383     }
384 
385 EXIT:
386     return NULL;
387 }
388 
389 /**
390  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_006
391  * @tc.name      : event operation for deatch
392  * @tc.desc      : [C- SOFTWARE -0200]
393  */
394 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread006, Function | MediumTest | Level1)
395 {
396     pthread_attr_t attr;
397     pthread_t newTh;
398     struct sched_param schedParam = { 0 };
399     UINT32 ret;
400 
401     ret = pthread_mutex_init(&g_pthread_mutex, NULL);
402     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
403 
404     ret = pthread_cond_init(&g_pthread_cond, NULL);
405     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
406 
407     ret = pthread_attr_init(&attr);
408     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
409 
410     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
411     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
412 
413     schedParam.sched_priority = TASK_PRIO_TEST - 1;
414     ret = pthread_attr_setschedparam(&attr, &schedParam);
415     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
416 
417     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
418     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
419 
420     ret = pthread_create(&newTh, &attr, pthread_f06, NULL);
421     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
422 
423     ret = pthread_join(newTh, NULL);
424     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
425 
426     return LOS_OK;
427 };
428 
pthread_cond_func002(void * arg)429 static void *pthread_cond_func002(void *arg)
430 {
431     int ret;
432     struct timespec ts;
433 
434     g_testCount++;
435 
436     ret = pthread_mutex_lock(&g_pthread_mutex);
437     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
438 
439     clock_gettime(CLOCK_REALTIME, &ts);
440     ts.tv_sec += 60; /* 60: wait 1 minute */
441 
442     ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
443     ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT);
444 
445     ret = pthread_mutex_unlock(&g_pthread_mutex);
446     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
447 
448     g_testCount++;
449 
450 EXIT:
451     return NULL;
452 }
453 
pthread_f07(void * argument)454 static VOID *pthread_f07(void *argument)
455 {
456     int policy;
457     int ret;
458     int i;
459     pthread_attr_t attr;
460     struct sched_param schedParam = { 0 };
461     pthread_t thread[TEST_THREAD_COUNT];
462 
463     g_testCount = 0;
464 
465     ret = pthread_attr_init(&attr);
466     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
467 
468     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
469     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
470 
471     ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
472     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
473 
474     schedParam.sched_priority -= 1;
475     ret = pthread_attr_setschedparam(&attr, &schedParam);
476     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
477 
478     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
479     ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
480 
481     for (i = 0; i < TEST_THREAD_COUNT; i++) {
482         ret = pthread_create(&thread[i], &attr, pthread_cond_func002, NULL);
483         ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
484     }
485 
486     ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
487 
488     for (i = 0; i < TEST_THREAD_COUNT; i++) {
489         ret = pthread_join(thread[i], NULL);
490         ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
491     }
492 
493     ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
494 
495 EXIT:
496     return NULL;
497 }
498 
499 /**
500  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_007
501  * @tc.name      : event operation for deatch
502  * @tc.desc      : [C- SOFTWARE -0200]
503  */
504 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread007, Function | MediumTest | Level1)
505 {
506     pthread_attr_t attr;
507     pthread_t newTh;
508     struct sched_param schedParam = { 0 };
509     UINT32 ret;
510 
511     ret = pthread_mutex_init(&g_pthread_mutex, NULL);
512     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
513 
514     ret = pthread_cond_init(&g_pthread_cond, NULL);
515     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
516 
517     ret = pthread_attr_init(&attr);
518     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
519 
520     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
521     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
522 
523     schedParam.sched_priority = TASK_PRIO_TEST - 1;
524     ret = pthread_attr_setschedparam(&attr, &schedParam);
525     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
526 
527     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
528     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
529 
530     ret = pthread_create(&newTh, &attr, pthread_f07, NULL);
531     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
532 
533     ret = pthread_join(newTh, NULL);
534     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
535 
536     return LOS_OK;
537 };
538 
539 static int g_pthreadKey1;
540 static int g_pthreadKey2;
pthreadKeyFree(void * data)541 static void pthreadKeyFree(void *data)
542 {
543     if (data != NULL) {
544         free(data);
545     }
546 }
547 
pthread_f08(void * arg)548 static void *pthread_f08(void *arg)
549 {
550 #define TEST_KEY_SIZE 0x100
551     int *data = (int *)malloc(TEST_KEY_SIZE);
552     if (data == NULL) {
553         return (void *)ENOMEM;
554     }
555 
556     (void)memset_s(data, TEST_KEY_SIZE, 0, TEST_KEY_SIZE);
557     *data = 100 + (int)pthread_self(); /* 100: test data */
558     int ret = pthread_setspecific(g_pthreadKey1, (void *)data);
559     if (ret != 0) {
560         return (void *)ret;
561     }
562 
563     data = (int *)malloc(TEST_KEY_SIZE);
564     if (data == NULL) {
565         return (void *)ENOMEM;
566     }
567 
568     (void)memset_s(data, TEST_KEY_SIZE, 0, TEST_KEY_SIZE);
569     *data = 200 + (int)pthread_self(); /* 200: test data */
570     ret = pthread_setspecific(g_pthreadKey2, (void *)data);
571     if (ret != 0) {
572         return (void *)ret;
573     }
574 
575     int *result = (int *)pthread_getspecific(g_pthreadKey1);
576     if (result == NULL) {
577         return (void *)EINVAL;
578     }
579 
580     if (*result != (100 + (int)pthread_self())) { /* 100: test data */
581         return (void *)EDEADLK;
582     }
583 
584     result = (int *)pthread_getspecific(g_pthreadKey2);
585     if (result == NULL) {
586         return (void *)EINVAL;
587     }
588 
589     if (*result != (200 + (int)pthread_self())) { /* 200: test data */
590         return (void *)EDEADLK;
591     }
592 
593     return NULL;
594 }
595 
596 /**
597  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_008
598  * @tc.name      : event operation for deatch
599  * @tc.desc      : [C- SOFTWARE -0200]
600  */
601 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread008, Function | MediumTest | Level1)
602 {
603     pthread_attr_t attr;
604     pthread_t newTh1, newTh2;
605     struct sched_param schedParam = { 0 };
606     int result = 0;
607     UINT32 ret;
608 
609     ret = pthread_key_create(&g_pthreadKey1, pthreadKeyFree);
610     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
611 
612     ret = pthread_key_create(&g_pthreadKey2, pthreadKeyFree);
613     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
614 
615     ret = pthread_attr_init(&attr);
616     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
617 
618     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
619     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
620 
621     schedParam.sched_priority = TASK_PRIO_TEST - 1;
622     ret = pthread_attr_setschedparam(&attr, &schedParam);
623     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
624 
625     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
626     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
627 
628     ret = pthread_create(&newTh1, &attr, pthread_f08, NULL);
629     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
630 
631     ret = pthread_create(&newTh2, &attr, pthread_f08, NULL);
632     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
633 
634     ret = pthread_join(newTh1, (void **)&result);
635     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
636     ICUNIT_ASSERT_EQUAL(result, 0, result);
637 
638     ret = pthread_join(newTh2, (void **)&result);
639     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
640     ICUNIT_ASSERT_EQUAL(result, 0, result);
641 
642     ret = pthread_key_delete(g_pthreadKey1);
643     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
644 
645     ret = pthread_key_delete(g_pthreadKey2);
646     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
647     return LOS_OK;
648 };
649 
pthread_prio_f01(void * argument)650 static VOID *pthread_prio_f01(void *argument)
651 {
652     g_testCount++;
653     ICUNIT_ASSERT_EQUAL(g_testCount, (UINT32)argument, g_testCount);
654     return NULL;
655 }
656 
657 /**
658  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_009
659  * @tc.name      : event operation for set priority
660  * @tc.desc      : [C- SOFTWARE -0200]
661  */
662 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread009, Function | MediumTest | Level1)
663 {
664     pthread_attr_t attr;
665     pthread_t thread[TEST_THREAD_COUNT];
666     struct sched_param schedParam = { 0 };
667     UINT32 ret;
668     UINT32 i = 0;
669     g_testCount = 0;
670     ret = pthread_attr_init(&attr);
671     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
672 
673     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
674     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
675 
676     schedParam.sched_priority = TASK_PRIO_TEST + 1;
677     ret = pthread_attr_setschedparam(&attr, &schedParam);
678     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
679 
680     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
681     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
682 
683     for (i = 0; i < TEST_THREAD_COUNT; i++) {
684         ret = pthread_create(&thread[i], &attr, pthread_prio_f01, TEST_THREAD_COUNT - i);
685         ICUNIT_ASSERT_EQUAL(ret, 0, ret);
686     }
687 
688     for (i = 0; i < TEST_THREAD_COUNT; i++) {
689         ret = pthread_setschedprio(thread[i], TASK_PRIO_TEST + TEST_THREAD_COUNT - i);
690         ICUNIT_ASSERT_EQUAL(ret, 0, ret);
691     }
692 
693     for (i = 0; i < TEST_THREAD_COUNT; i++) {
694         ret = pthread_join(thread[i], NULL);
695         ICUNIT_ASSERT_EQUAL(ret, 0, ret);
696     }
697 
698     return LOS_OK;
699 };
700 
pthread_once_f01(void)701 static VOID pthread_once_f01(void)
702 {
703     g_testCount++;
704     ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
705 }
706 
707 /**
708  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_010
709  * @tc.name      : event operation for pthread_once
710  * @tc.desc      : [C- SOFTWARE -0200]
711  */
712 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread010, Function | MediumTest | Level1)
713 {
714     pthread_attr_t attr;
715     pthread_t thread[TEST_THREAD_COUNT];
716     struct sched_param schedParam = { 0 };
717     UINT32 ret;
718     UINT32 i = 0;
719     pthread_once_t onceControl = 0;
720     g_testCount = 0;
721     ret = pthread_attr_init(&attr);
722     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
723 
724     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
725     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
726 
727     schedParam.sched_priority = TASK_PRIO_TEST + 1;
728     ret = pthread_attr_setschedparam(&attr, &schedParam);
729     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
730 
731     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
732     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
733 
734     for (i = 0; i < TEST_THREAD_COUNT; i++) {
735         ret = pthread_once(&onceControl, pthread_once_f01);
736         ICUNIT_ASSERT_EQUAL(ret, 0, ret);
737     }
738     ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
739 
740     return LOS_OK;
741 };
742 
pthread_cancel_f01(void * argument)743 static VOID *pthread_cancel_f01(void *argument)
744 {
745     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
746     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
747     while (1) {
748         g_testCount++;
749         ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
750         LOS_TaskDelay(PTHREAD_TASK_DELAY);
751     }
752 
753     return NULL;
754 }
755 
756 /**
757  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_011
758  * @tc.name      : event operation for pthread_cancel
759  * @tc.desc      : [C- SOFTWARE -0200]
760  */
761 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread011, Function | MediumTest | Level1)
762 {
763     pthread_attr_t attr;
764     pthread_t thread;
765     struct sched_param schedParam = { 0 };
766     UINT32 ret;
767     g_testCount = 0;
768     ret = pthread_attr_init(&attr);
769     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
770 
771     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
772     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
773 
774     schedParam.sched_priority = TASK_PRIO_TEST - 1;
775     ret = pthread_attr_setschedparam(&attr, &schedParam);
776     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
777 
778     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
779     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
780 
781     ret = pthread_create(&thread, &attr, pthread_cancel_f01, NULL);
782     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
783 
784     ret = pthread_cancel(thread);
785     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
786 
787     ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
788 
789     return LOS_OK;
790 };
791 
pthread_testcancel_f01(void * argument)792 static VOID *pthread_testcancel_f01(void *argument)
793 {
794     INT32 ret = 0;
795 
796     ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
797     ICUNIT_TRACK_EQUAL(ret, 0, ret);
798 
799     ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
800     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
801 
802     g_testCount = 1;
803     g_pthreadSem = 1;
804     while (g_pthreadSem == 1) {
805         LOS_TaskDelay(PTHREAD_TASK_DELAY);
806     }
807 
808     LOS_TaskDelay(PTHREAD_TASK_DELAY);
809     pthread_testcancel();
810     g_testCount = -1;
811 
812     return NULL;
813 }
814 
815 /**
816  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_012
817  * @tc.name      : event operation for testcancel
818  * @tc.desc      : [C- SOFTWARE -0200]
819  */
820 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread012, Function | MediumTest | Level1)
821 {
822     pthread_attr_t attr;
823     pthread_t thread;
824     struct sched_param schedParam = { 0 };
825     UINT32 ret;
826 
827     g_testCount = 0;
828     g_pthreadSem = 0;
829 
830     ret = pthread_attr_init(&attr);
831     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
832 
833     ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
834     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
835 
836     schedParam.sched_priority = TASK_PRIO_TEST - 1;
837     ret = pthread_attr_setschedparam(&attr, &schedParam);
838     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
839 
840     ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
841     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
842 
843     ret = pthread_create(&thread, &attr, pthread_testcancel_f01, NULL);
844     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
845 
846     while (g_pthreadSem == 0) {
847         LOS_TaskDelay(PTHREAD_TASK_DELAY);
848     }
849 
850     ret = pthread_cancel(thread);
851     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
852 
853     g_pthreadSem = 0;
854 
855     ret = pthread_join(thread, NULL);
856     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
857     ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
858 
859     return LOS_OK;
860 };
861 
862 /**
863  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_013
864  * @tc.name      : event operation for set/get clock
865  * @tc.desc      : [C- SOFTWARE -0200]
866  */
867 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread013, Function | MediumTest | Level1)
868 {
869     INT32 ret;
870     clockid_t clk;
871     const int invalidClock = -100;
872     pthread_condattr_t condattr;
873     ret = pthread_condattr_init(&condattr);
874     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
875 
876     ret = pthread_condattr_getclock(&condattr, &clk);
877     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
878     ICUNIT_ASSERT_EQUAL(clk, 0, clk);
879 
880     ret = pthread_condattr_setclock(&condattr, 0);
881     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
882     ret = pthread_condattr_getclock(&condattr, &clk);
883     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
884     ICUNIT_ASSERT_EQUAL(clk, 0, clk);
885 
886     struct timespec ts = {0};
887     ret = clock_getres(CLOCK_MONOTONIC, &ts);
888     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
889     ret = pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
890     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
891     ret = pthread_condattr_getclock(&condattr, &clk);
892     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
893     ICUNIT_ASSERT_EQUAL(clk, CLOCK_MONOTONIC, clk);
894 
895     ret = pthread_condattr_setclock(&condattr, invalidClock);
896     ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
897 
898     return 0;
899 }
900 
901 /**
902  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_014
903  * @tc.name      : event operation for setpshared
904  * @tc.desc      : [C- SOFTWARE -0200]
905  */
906 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread014, Function | MediumTest | Level1)
907 {
908     INT32 ret;
909     pthread_condattr_t attr;
910 
911     /* Initialize a cond attributes object */
912     ret = pthread_condattr_init(&attr);
913     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
914 
915     /* Set 'pshared' to INVALID_PSHARED_VALUE. */
916     ret = pthread_condattr_setpshared(&attr, (-100));
917     ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
918 
919     /* Destroy the cond attributes object */
920     ret = pthread_condattr_destroy(&attr);
921     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
922 
923     return 0;
924 }
925 
926 /**
927  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_015
928  * @tc.name      : event operation for getpshared
929  * @tc.desc      : [C- SOFTWARE -0200]
930  */
931 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread015, Function | MediumTest | Level1)
932 {
933     INT32 ret;
934     INT32 pshared;
935     pthread_condattr_t attr;
936 
937     /* Initialize a cond attributes object */
938     ret = pthread_condattr_init(&attr);
939     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
940 
941     /* Set 'pshared' to INVALID_PSHARED_VALUE. */
942     ret = pthread_condattr_getpshared(&attr, &pshared);
943     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
944     ICUNIT_ASSERT_EQUAL(pshared, PTHREAD_PROCESS_PRIVATE, pshared);
945 
946     /* Destroy the cond attributes object */
947     ret = pthread_condattr_destroy(&attr);
948     ICUNIT_ASSERT_EQUAL(ret, 0, ret);
949 
950     return 0;
951 }
952 
953 /**
954  * @tc.number    : SUB_KERNEL_PTHREAD_OPERATION_016
955  * @tc.name      : event operation for get/set mutex attr
956  * @tc.desc      : [C- SOFTWARE -0200]
957  */
958 LITE_TEST_CASE(PthreadFuncTestSuite, testPthread016, Function | MediumTest | Level1)
959 {
960     pthread_mutexattr_t mutex_attr;
961     int mutex_type;
962     int ret;
963     pthread_mutexattr_init(&mutex_attr);
964     ret = pthread_mutexattr_settype(NULL, PTHREAD_MUTEX_ERRORCHECK);
965     if (ret == 0) {
966         ICUNIT_ASSERT_EQUAL(ret, 0, ret);
967     }
968     pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
969     pthread_mutexattr_gettype(&mutex_attr, &mutex_type);
970     if (mutex_type != PTHREAD_MUTEX_ERRORCHECK) {
971         ICUNIT_ASSERT_EQUAL(mutex_type, 0, mutex_type);
972     }
973     ret = pthread_mutexattr_gettype(NULL, &mutex_type);
974     if (ret == 0) {
975         ICUNIT_ASSERT_EQUAL(ret, 0, ret);
976     }
977     mutex_attr.type = 3;
978     ret = pthread_mutexattr_gettype(&mutex_attr, &mutex_type);
979     if (ret == 0) {
980         ICUNIT_ASSERT_EQUAL(ret, 0, ret);
981     }
982     return LOS_OK;
983 }
984 
985 RUN_TEST_SUITE(PthreadFuncTestSuite);
986 
987