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