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
45static 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
58static 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 */
71LITE_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
104static 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 */
116LITE_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
149static VOID *PthreadJoinF03(void *argument)
150{
151    int ret = pthread_detach(pthread_self());
152    ICUNIT_GOTO_EQUAL(ret, ESRCH, ret, EXIT);
153
154    g_testCount++;
155EXIT:
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 */
164LITE_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
196static VOID *PthreadJoinF04(void *argument)
197{
198    int ret = pthread_detach(pthread_self());
199    ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
200
201    g_testCount++;
202EXIT:
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 */
211LITE_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
244static 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 */
250EXIT:
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 */
259LITE_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
291static pthread_cond_t g_pthread_cond;
292static pthread_mutex_t g_pthread_mutex;
293#define TEST_THREAD_COUNT 5
294static 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++;
314EXIT:
315    return NULL;
316}
317
318static 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
368EXIT:
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 */
377LITE_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
412static 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
432EXIT:
433    return NULL;
434}
435
436static 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
480EXIT:
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 */
489LITE_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
521static int g_pthreadKey1;
522static int g_pthreadKey2;
523static void pthreadKeyFree(void *data)
524{
525    if (data != NULL) {
526        free(data);
527    }
528}
529
530static 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 */
583LITE_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
632static 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 */
644LITE_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
683static 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 */
695LITE_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
725static 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
735EXIT:
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 */
744LITE_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
775static 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
795EXIT:
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 */
804LITE_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 */
851LITE_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 */
890LITE_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 */
914LITE_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 */
941LITE_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
965static 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 */
977LITE_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
1000EXIT:
1001    free(stackAddr);
1002    return LOS_OK;
1003};
1004
1005static 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
1027static void *PosixTestThread(void *arg)
1028{
1029    PosixTestCase();
1030    return NULL;
1031}
1032int 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