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