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