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