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