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