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