1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <unistd.h>
17 #include <pthread.h>
18 #include <semaphore.h>
19 #include <sys/resource.h>
20 #include <gtest/gtest.h>
21 #include "log.h"
22 #include "utils.h"
23 #include "mt_utils.h"
24 #include "KernelConstants.h"
25 
26 using namespace testing::ext;
27 // global variables used to communicate between threads
28 static int g_policy = 0;
29 static int g_prioriy = 0;
30 
31 class PthreadSchedApiTest : public testing::Test {
32 };
33 class PthreadAllPrioTest : public testing::TestWithParam<int> {
34 };
35 
36 /**
37  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_INHERIT_0100
38  * @tc.name     test the default value of inheritsched.
39  * @tc.desc     [C- SOFTWARE -0200]
40  */
HWTEST_F(PthreadSchedApiTest, testAttrGetInheritsched, Function | MediumTest | Level1)41 HWTEST_F(PthreadSchedApiTest, testAttrGetInheritsched, Function | MediumTest | Level1)
42 {
43     pthread_attr_t attr;
44     ASSERT_EQ(pthread_attr_init(&attr), 0);
45 
46     int inheritsched = -1;
47     int rt = pthread_attr_getinheritsched(&attr, &inheritsched);
48     EXPECT_EQ(rt, 0) << "pthread_attr_getinheritsched failed. errno=" << errno;
49     EXPECT_EQ(inheritsched, PTHREAD_INHERIT_SCHED)
50         << "check default inheritsched failed. expect PTHREAD_INHERIT_SCHED";
51 }
52 
53 /**
54  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_INHERIT_0200
55  * @tc.name     test set and get inheritsched.
56  * @tc.desc     [C- SOFTWARE -0200]
57  */
HWTEST_F(PthreadSchedApiTest, testAttrSetInheritsched, Function | MediumTest | Level1)58 HWTEST_F(PthreadSchedApiTest, testAttrSetInheritsched, Function | MediumTest | Level1)
59 {
60     pthread_attr_t attr;
61     ASSERT_EQ(pthread_attr_init(&attr), 0);
62 
63     int rt = pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
64     EXPECT_EQ(rt, 0) << "pthread_attr_setinheritsched failed. errno=" << errno;
65     int inheritsched = -1;
66     rt = pthread_attr_getinheritsched(&attr, &inheritsched);
67     EXPECT_EQ(rt, 0) << "pthread_attr_getinheritsched failed. errno=" << errno;
68     EXPECT_EQ(inheritsched, PTHREAD_INHERIT_SCHED) << "check inheritsched failed";
69 
70     rt = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
71     EXPECT_EQ(rt, 0) << "pthread_attr_setinheritsched failed. errno=" << errno;
72     inheritsched = -1;
73     rt = pthread_attr_getinheritsched(&attr, &inheritsched);
74     EXPECT_EQ(rt, 0) << "pthread_attr_getinheritsched failed. errno=" << errno;
75     EXPECT_EQ(inheritsched, PTHREAD_EXPLICIT_SCHED) << "check inheritsched failed";
76 }
77 
78 /**
79  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_INHERIT_0300
80  * @tc.name     pthread_attr_setinheritsched error test.
81  * @tc.desc     [C- SOFTWARE -0200]
82  */
HWTEST_F(PthreadSchedApiTest, testAttrSetInheritschedError, Function | MediumTest | Level1)83 HWTEST_F(PthreadSchedApiTest, testAttrSetInheritschedError, Function | MediumTest | Level1)
84 {
85     pthread_attr_t attr;
86     ASSERT_EQ(pthread_attr_init(&attr), 0);
87 
88     int n = -GetRandom(100);
89     int rt = pthread_attr_setinheritsched(&attr, n);
90     EXPECT_EQ(rt, EINVAL) << "pthread_attr_setinheritsched(" << n << ") should fail";
91     n = 2 + GetRandom(100);
92     rt = pthread_attr_setinheritsched(&attr, n);
93     EXPECT_EQ(rt, EINVAL) << "pthread_attr_setinheritsched(" << n << ") should fail";
94 }
95 
96 /**
97  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCHEDPARAM_0100
98  * @tc.name     test the default value of sched_param.
99  * @tc.desc     [C- SOFTWARE -0200]
100  */
HWTEST_F(PthreadSchedApiTest, testAttrGetSchedParam, Function | MediumTest | Level1)101 HWTEST_F(PthreadSchedApiTest, testAttrGetSchedParam, Function | MediumTest | Level1)
102 {
103     pthread_attr_t attr;
104     ASSERT_EQ(pthread_attr_init(&attr), 0);
105 
106     struct sched_param param = {0};
107     int rt = pthread_attr_getschedparam(&attr, &param);
108     EXPECT_EQ(rt, 0) << "pthread_attr_getschedparam failed. errno=" << errno;
109     EXPECT_EQ(param.sched_priority, DEFAULT_THREAD_PRIORITY) << "check default pthread priority failed";
110 }
111 
112 /**
113  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCHEDPARAM_0200
114  * @tc.name     test set and get sched param.
115  * @tc.desc     [C- SOFTWARE -0200]
116  */
HWTEST_F(PthreadSchedApiTest, testAttrSetSchedParam, Function | MediumTest | Level1)117 HWTEST_F(PthreadSchedApiTest, testAttrSetSchedParam, Function | MediumTest | Level1)
118 {
119     pthread_attr_t attr;
120     ASSERT_EQ(pthread_attr_init(&attr), 0);
121 
122     struct sched_param param = {0};
123     int rt = pthread_attr_getschedparam(&attr, &param);
124     EXPECT_EQ(rt, 0) << "pthread_attr_getschedparam failed. errno=" << errno;
125 
126     param.sched_priority = 22;
127     rt = pthread_attr_setschedparam(&attr, &param);
128     EXPECT_EQ(rt, 0) << "pthread_attr_setschedparam failed. errno=" << errno;
129 
130     rt = pthread_attr_getschedparam(&attr, &param);
131     EXPECT_EQ(rt, 0) << "pthread_attr_getschedparam failed. errno=" << errno;
132     EXPECT_EQ(param.sched_priority, 22) << "check pthread priority failed";
133 }
134 
135 /**
136  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCHEDPARAM_0300
137  * @tc.name     pthread_attr_setschedparam error test.
138  * @tc.desc     [C- SOFTWARE -0200]
139  */
HWTEST_F(PthreadSchedApiTest, testAttrSetSchedParamError, Function | MediumTest | Level1)140 HWTEST_F(PthreadSchedApiTest, testAttrSetSchedParamError, Function | MediumTest | Level1)
141 {
142     pthread_attr_t attr;
143     ASSERT_EQ(pthread_attr_init(&attr), 0);
144 
145     struct sched_param param = {0};
146     int rt = pthread_attr_getschedparam(&attr, &param);
147     EXPECT_EQ(rt, 0) << "pthread_attr_getschedparam failed. errno=" << errno;
148 
149     param.sched_priority = LOWEST_USER_THREAD_PRIORITY + 1;
150     rt = pthread_attr_setschedparam(&attr, &param);
151     EXPECT_EQ(rt, EINVAL);
152 }
153 
154 /**
155  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCHEDPOLICY_0100
156  * @tc.name     test the default value of sched policy.
157  * @tc.desc     [C- SOFTWARE -0200]
158  */
HWTEST_F(PthreadSchedApiTest, testAttrGetSchedPolicy, Function | MediumTest | Level1)159 HWTEST_F(PthreadSchedApiTest, testAttrGetSchedPolicy, Function | MediumTest | Level1)
160 {
161     pthread_attr_t attr;
162     ASSERT_EQ(pthread_attr_init(&attr), 0);
163 
164     int policy = -1;
165     int rt = pthread_attr_getschedpolicy(&attr, &policy);
166     EXPECT_EQ(rt, 0) << "pthread_attr_getschedpolicy failed. errno=" << errno;
167     EXPECT_EQ(policy, SCHED_RR) << "check default policy failed, expect SCHED_RR";
168 }
169 
170 /**
171  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCHEDPOLICY_0200
172  * @tc.name     test set and get sched policy.
173  * @tc.desc     [C- SOFTWARE -0200]
174  */
HWTEST_F(PthreadSchedApiTest, testAttrSetSchedPolicy, Function | MediumTest | Level1)175 HWTEST_F(PthreadSchedApiTest, testAttrSetSchedPolicy, Function | MediumTest | Level1)
176 {
177     pthread_attr_t attr;
178     ASSERT_EQ(pthread_attr_init(&attr), 0);
179 
180     int rt = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
181     EXPECT_EQ(rt, 0) << "pthread_attr_setschedparam failed. errno=" << errno;
182     int policy = -1;
183     rt = pthread_attr_getschedpolicy(&attr, &policy);
184     EXPECT_EQ(rt, 0) << "pthread_attr_getschedpolicy failed. errno=" << errno;
185     EXPECT_EQ(policy, SCHED_FIFO);
186 
187     rt = pthread_attr_setschedpolicy(&attr, SCHED_RR);
188     EXPECT_EQ(rt, 0) << "pthread_attr_setschedparam failed. errno=" << errno;
189     rt = pthread_attr_getschedpolicy(&attr, &policy);
190     EXPECT_EQ(rt, 0) << "pthread_attr_getschedpolicy failed. errno=" << errno;
191     EXPECT_EQ(policy, SCHED_RR);
192 }
193 
194 /**
195  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCHEDPOLICY_0300
196  * @tc.name     pthread_attr_setschedpolicy error test.
197  * @tc.desc     [C- SOFTWARE -0200]
198  */
HWTEST_F(PthreadSchedApiTest, testAttrSetSchedPolicyError, Function | MediumTest | Level1)199 HWTEST_F(PthreadSchedApiTest, testAttrSetSchedPolicyError, Function | MediumTest | Level1)
200 {
201     pthread_attr_t attr;
202     ASSERT_EQ(pthread_attr_init(&attr), 0);
203     int rt;
204 
205     // SCHED_FIFO is 1, and SCHED_RR is 2
206     const int testLoop = 7;
207     int invalidPolicy[testLoop] = {SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_RESET_ON_FORK};
208     invalidPolicy[4] = GetRandom(10000);
209     invalidPolicy[5] = -GetRandom(10000) + 6;
210     invalidPolicy[6] = GetRandom(10000) + 6;
211     for (int i = 0; i < testLoop; i++) {
212         rt = pthread_attr_setschedpolicy(&attr, invalidPolicy[i]);
213         EXPECT_EQ(rt, EINVAL) << "errno check fail for policy=" << invalidPolicy[i];
214     }
215 }
216 
217 /**
218  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCOPE_0100
219  * @tc.name     test the default value of sched scope.
220  * @tc.desc     [C- SOFTWARE -0200]
221  */
HWTEST_F(PthreadSchedApiTest, testAttrGetScope, Function | MediumTest | Level1)222 HWTEST_F(PthreadSchedApiTest, testAttrGetScope, Function | MediumTest | Level1)
223 {
224     pthread_attr_t attr;
225     ASSERT_EQ(pthread_attr_init(&attr), 0);
226 
227     int scope = -1;
228     int rt = pthread_attr_getscope(&attr, &scope);
229     EXPECT_EQ(rt, 0) << "pthread_attr_getscope failed. errno=" << errno;
230     EXPECT_EQ(scope, PTHREAD_SCOPE_PROCESS) << "check default scope failed. expect PTHREAD_SCOPE_PROCESS";
231 }
232 
233 /**
234  * @tc.number   SUB_KERNEL_SCHED_API_PATTR_SCOPE_0200
235  * @tc.name     test set and get scope.
236  * @tc.desc     [C- SOFTWARE -0200]
237  */
HWTEST_F(PthreadSchedApiTest, testAttrSetScope, Function | MediumTest | Level1)238 HWTEST_F(PthreadSchedApiTest, testAttrSetScope, Function | MediumTest | Level1)
239 {
240     pthread_attr_t attr;
241     ASSERT_EQ(pthread_attr_init(&attr), 0);
242 
243     int rt = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
244     EXPECT_EQ(rt, ENOTSUP); // liteos support PTHREAD_SCOPE_PROCESS only
245 
246     rt = pthread_attr_setscope(&attr, -GetRandom(10000));
247     EXPECT_EQ(rt, EINVAL);
248 
249     rt = pthread_attr_setscope(&attr, GetRandom(10000) + 2);
250     EXPECT_EQ(rt, EINVAL);
251 
252     int scope = -1;
253     rt = pthread_attr_getscope(&attr, &scope);
254     EXPECT_EQ(rt, 0) << "pthread_attr_getscope failed. errno=" << errno;
255     EXPECT_EQ(scope, PTHREAD_SCOPE_PROCESS) << "check scope failed. expect PTHREAD_SCOPE_PROCESS";
256 }
257 
ThreadFunc1(void* arg)258 void* ThreadFunc1(void* arg)
259 {
260     sem_t *sem = (sem_t*)arg;
261 
262     int policy;
263     struct sched_param param = {0};
264     EXPECT_EQ(pthread_getschedparam(pthread_self(), &policy, &param), 0);
265     EXPECT_EQ(policy, g_policy);
266     EXPECT_EQ(param.sched_priority, g_prioriy);
267 
268     LOG("wait main thread check this thread para...");
269     sem_wait(sem);
270     return nullptr;
271 }
272 /**
273  * @tc.number   SUB_KERNEL_SCHED_API_PTHREAD_GETSCHEDPARAM_0100
274  * @tc.name     pthread_getschedparam basic test.
275  * @tc.desc     [C- SOFTWARE -0200]
276  */
HWTEST_F(PthreadSchedApiTest, testGetSchedParam, Function | MediumTest | Level1)277 HWTEST_F(PthreadSchedApiTest, testGetSchedParam, Function | MediumTest | Level1)
278 {
279     sem_t sem;
280     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "sem_init errno = " << errno;
281 
282     pthread_t ptSub;
283     pthread_attr_t attr;
284     struct sched_param param = {0};
285     ASSERT_EQ(pthread_attr_init(&attr), 0);
286     g_policy = SCHED_FIFO;
287     param.sched_priority = g_prioriy = GetRandom(LOWEST_USER_THREAD_PRIORITY);
288 
289     EXPECT_EQ(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED), 0);
290     EXPECT_EQ(pthread_attr_setschedpolicy(&attr, g_policy), 0);
291     EXPECT_EQ(pthread_attr_setschedparam(&attr, &param), 0);
292     int rt = pthread_create(&ptSub, &attr, ThreadFunc1, (void*)&sem);
293     ASSERT_EQ(rt, 0) << "pthread_create failed!";
294 
295     LOG("check sub thread's para");
296     int policy;
297     EXPECT_EQ(pthread_getschedparam(ptSub, &policy, &param), 0);
298     EXPECT_EQ(policy, g_policy);
299     EXPECT_EQ(param.sched_priority, g_prioriy);
300 
301     LOGD("main:before post sem...");
302     sem_post(&sem);
303     LOGD("main:after post sem...");
304     pthread_join(ptSub, nullptr);
305 }
306 
307 /**
308  * @tc.number   SUB_KERNEL_SCHED_API_PTHREAD_SETSCHEDPARAM_0100
309  * @tc.name     pthread_setschedparam basic test.
310  * @tc.desc     [C- SOFTWARE -0200]
311  */
HWTEST_P(PthreadAllPrioTest, testSetSchedParam, Function | MediumTest | Level1)312 HWTEST_P(PthreadAllPrioTest, testSetSchedParam, Function | MediumTest | Level1)
313 {
314     pthread_t ptSub;
315     pthread_t ptSelf = pthread_self();
316     sem_t sem;
317     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "sem_init errno = " << errno;
318 
319     // change self sched para
320     struct sched_param param = {0};
321     int policy;
322     EXPECT_EQ(pthread_getschedparam(ptSelf, &policy, &param), 0);
323     param.sched_priority = g_prioriy = GetParam();
324     if (GetRandom(100)%2) {
325         policy = g_policy = SCHED_RR;
326     } else {
327         policy = g_policy = SCHED_FIFO;
328     }
329     LOG("========= Test policy(%d) and prioriy(%d) =========", g_policy, g_prioriy);
330 
331     int rt = pthread_setschedparam(ptSelf, policy, &param);
332     ASSERT_EQ(rt, 0) << "pthread_setschedparam failed!";
333 
334     LOG("create sub thread");
335     pthread_attr_t attr;
336     ASSERT_EQ(pthread_attr_init(&attr), 0);
337     EXPECT_EQ(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED), 0);
338     rt = pthread_create(&ptSub, &attr, ThreadFunc1, (void*)&sem);
339     ASSERT_EQ(rt, 0) << "pthread_create failed!";
340 
341     LOG("check self and sub thread's para");
342     EXPECT_EQ(pthread_getschedparam(ptSelf, &policy, &param), 0);
343     EXPECT_EQ(policy, g_policy);
344     EXPECT_EQ(param.sched_priority, g_prioriy);
345 
346     EXPECT_EQ(pthread_getschedparam(ptSub, &policy, &param), 0);
347     EXPECT_EQ(policy, g_policy);
348     EXPECT_EQ(param.sched_priority, g_prioriy);
349 
350     LOGD("main:before post sem...");
351     sem_post(&sem);
352     LOGD("main:after post sem...");
353     pthread_join(ptSub, nullptr);
354 
355 
356     LOG("restore...");
357     policy = SCHED_RR;
358     param.sched_priority = DEFAULT_THREAD_PRIORITY;
359     rt = pthread_setschedparam(ptSelf, policy, &param);
360     ASSERT_EQ(rt, 0) << "pthread_setschedparam failed!";
361 }
362 INSTANTIATE_TEST_CASE_P(PthreadSchedApiTest, PthreadAllPrioTest,
363     testing::Range(HIGHEST_USER_THREAD_PRIORITY, LOWEST_USER_THREAD_PRIORITY + 1));
364 
ThrdFuncForSetSchedParamTest(void* arg)365 void* ThrdFuncForSetSchedParamTest(void* arg)
366 {
367     sem_t *sem = (sem_t*)arg;
368     pthread_t ptSelf = pthread_self();
369     int rt, policy;
370     struct sched_param param = {0};
371     EXPECT_EQ(pthread_getschedparam(ptSelf, &policy, &param), 0);
372 
373     LOG("invalid policy test:");
374     const int testLoop = 7;
375     int invalidPolicy[testLoop] = {
376         SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_DEADLINE, SCHED_RESET_ON_FORK,
377         -(int)GetRandom(10000), (int)GetRandom(10000) + SCHED_DEADLINE
378     };
379     for (int i = 0; i < testLoop; i++) {
380         rt = pthread_setschedparam(ptSelf, invalidPolicy[i], &param);
381         EXPECT_EQ(rt, EINVAL) << "pthread_setschedparam should fail for policy=" << invalidPolicy[i];
382     }
383 
384     LOG("invalid 'priority' test:");
385     param.sched_priority = HIGHEST_USER_THREAD_PRIORITY - 1;
386     EXPECT_EQ(pthread_setschedparam(ptSelf, SCHED_RR, &param), EINVAL);
387     param.sched_priority = LOWEST_USER_THREAD_PRIORITY + 1;
388     EXPECT_EQ(pthread_setschedparam(ptSelf, SCHED_RR, &param), EINVAL);
389 
390     LOG("tell main thread check this thread para...");
391     sem_post(sem);
392     Msleep(100);
393     LOG("thread exit...");
394     return nullptr;
395 }
396 /**
397  * @tc.number   SUB_KERNEL_SCHED_API_PTHREAD_SETSCHEDPARAM_0200
398  * @tc.name     pthread_setschedparam api error test.
399  * @tc.desc     [C- SOFTWARE -0200]
400  */
HWTEST_F(PthreadSchedApiTest, testSetSchedParamError, Function | MediumTest | Level3)401 HWTEST_F(PthreadSchedApiTest, testSetSchedParamError, Function | MediumTest | Level3)
402 {
403     sem_t sem;
404     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "sem_init errno = " << errno;
405 
406     pthread_t ptSub;
407     pthread_attr_t attr;
408     struct sched_param param = {0};
409     ASSERT_EQ(pthread_attr_init(&attr), 0);
410     g_policy = SCHED_FIFO;
411     param.sched_priority = g_prioriy = GetRandom(LOWEST_USER_THREAD_PRIORITY);
412 
413     EXPECT_EQ(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED), 0);
414     EXPECT_EQ(pthread_attr_setschedpolicy(&attr, g_policy), 0);
415     EXPECT_EQ(pthread_attr_setschedparam(&attr, &param), 0);
416     int rt = pthread_create(&ptSub, &attr, ThrdFuncForSetSchedParamTest, (void*)&sem);
417     ASSERT_EQ(rt, 0) << "pthread_create failed!";
418 
419     LOGD("main:wait sub-thread...");
420     sem_wait(&sem);
421     LOG("check sub thread's para doesn't changed");
422     int policy;
423     EXPECT_EQ(pthread_getschedparam(ptSub, &policy, &param), 0);
424     EXPECT_EQ(policy, g_policy);
425     EXPECT_EQ(param.sched_priority, g_prioriy);
426 
427     pthread_join(ptSub, nullptr);
428 }
429 
ThrdFuncForSetSchedPrioTest(void* arg)430 void* ThrdFuncForSetSchedPrioTest(void* arg)
431 {
432     sem_t *sem = (sem_t*)arg;
433     pthread_t ptSelf = pthread_self();
434 
435     LOG("invalid 'priority' test:");
436     EXPECT_EQ(pthread_setschedprio(ptSelf, HIGHEST_USER_THREAD_PRIORITY - 1), EINVAL);
437     EXPECT_EQ(pthread_setschedprio(ptSelf, LOWEST_USER_THREAD_PRIORITY + 1), EINVAL);
438 
439     LOG("valid 'priority' test:");
440     EXPECT_EQ(pthread_setschedprio(ptSelf, LOWEST_USER_THREAD_PRIORITY), 0);
441 
442     LOG("tell main thread check this thread para...");
443     sem_post(sem);
444     Msleep(100);
445     LOG("thread exit...");
446     return nullptr;
447 }
448 /**
449  * @tc.number   SUB_KERNEL_SCHED_API_PTHREAD_SETSCHEDPRIO_0100
450  * @tc.name     pthread_setschedprio api basic test.
451  * @tc.desc     [C- SOFTWARE -0200]
452  */
HWTEST_F(PthreadSchedApiTest, testSetSchedPrio, Function | MediumTest | Level1)453 HWTEST_F(PthreadSchedApiTest, testSetSchedPrio, Function | MediumTest | Level1)
454 {
455     sem_t sem;
456     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "sem_init errno = " << errno;
457 
458     pthread_t ptSub;
459     pthread_attr_t attr;
460     struct sched_param param = {0};
461     ASSERT_EQ(pthread_attr_init(&attr), 0);
462     g_policy = SCHED_RR;
463     param.sched_priority = g_prioriy = HIGHEST_USER_THREAD_PRIORITY;
464 
465     EXPECT_EQ(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED), 0);
466     EXPECT_EQ(pthread_attr_setschedpolicy(&attr, g_policy), 0);
467     EXPECT_EQ(pthread_attr_setschedparam(&attr, &param), 0);
468     int rt = pthread_create(&ptSub, &attr, ThrdFuncForSetSchedPrioTest, (void*)&sem);
469     ASSERT_EQ(rt, 0) << "pthread_create failed!";
470 
471     LOGD("main:wait sub-thread...");
472     sem_wait(&sem);
473     LOG("check sub thread's priority has changed");
474     int policy;
475     EXPECT_EQ(pthread_getschedparam(ptSub, &policy, &param), 0);
476     EXPECT_EQ(policy, g_policy);
477     EXPECT_EQ(param.sched_priority, LOWEST_USER_THREAD_PRIORITY);
478     pthread_join(ptSub, nullptr);
479 }
480 
481 // second
ThreadTestFifoSched1(void *arg)482 void *ThreadTestFifoSched1(void *arg)
483 {
484     sem_t *sem = (sem_t*)arg;
485     EXPECT_EQ(sem_wait(sem), 0) << "sem_wait errno = " << errno;
486     CheckStep(3);
487     LOG("> This is ThreadSched1");
488     return arg;
489 }
490 
491 // first
ThreadTestFifoSched2(void *arg)492 void *ThreadTestFifoSched2(void *arg)
493 {
494     sem_t *sem = (sem_t*)arg;
495     EXPECT_EQ(sem_wait(sem), 0) << "sem_wait errno = " << errno;
496     CheckStep(2);
497     LOG("> This is ThreadSched2");
498     return arg;
499 }
500 
501 /**
502  * @tc.number   SUB_KERNEL_SCHED_API_PTHREAD_SCHED_ALL_0100
503  * @tc.name     test thread high ang low priority function
504  * @tc.desc     [C- SOFTWARE -0200]
505  */
HWTEST_F(PthreadSchedApiTest, testSchedFifo, Function | MediumTest | Level3)506 HWTEST_F(PthreadSchedApiTest, testSchedFifo, Function | MediumTest | Level3)
507 {
508     pthread_t tid1;
509     pthread_t tid2;
510     int param;
511     pthread_attr_t attr;
512     struct sched_param schedParam = {0};
513     sem_t sem;
514     CheckStep(1);
515 
516     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "> sem_init errno = " << errno;
517 
518     // low
519     EXPECT_EQ(pthread_attr_init(&attr), 0);
520     EXPECT_EQ(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED), 0) << "> return errno";
521     EXPECT_EQ(pthread_attr_setschedpolicy(&attr, SCHED_FIFO), 0) << "> return errno";
522     EXPECT_EQ(pthread_attr_getschedpolicy(&attr, &param), 0);
523     EXPECT_EQ(param, SCHED_FIFO);
524 
525     schedParam.sched_priority = 22;
526     EXPECT_EQ(pthread_attr_setschedparam(&attr, &schedParam), 0) << "> return errno";
527 
528     ASSERT_EQ(pthread_create(&tid1, &attr, ThreadTestFifoSched1, (void*)&sem), 0) << "> return errno";
529     EXPECT_EQ(pthread_attr_destroy(&attr), 0);
530 
531     // high
532     EXPECT_EQ(pthread_attr_init(&attr), 0);
533     EXPECT_EQ(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED), 0) << "> return errno";
534     EXPECT_EQ(pthread_attr_setschedpolicy(&attr, SCHED_FIFO), 0) << "> return errno";
535 
536     schedParam.sched_priority = 21;
537     EXPECT_EQ(pthread_attr_setschedparam(&attr, &schedParam), 0) << "> return errno";
538 
539     ASSERT_EQ(pthread_create(&tid2, &attr, ThreadTestFifoSched2, (void*)&sem), 0) << "> return errno";
540     EXPECT_EQ(pthread_attr_destroy(&attr), 0);
541 
542     Msleep(10);
543     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
544     Msleep(10);
545     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
546 
547     EXPECT_EQ(pthread_join(tid1, nullptr), 0) << "> return errno";
548     EXPECT_EQ(pthread_join(tid2, nullptr), 0) << "> return errno";
549 
550     EXPECT_EQ(CheckStep(4), 0x1234Ull);    // make sure ThreadTestFifoSched2 ahead
551 }