1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "los_sched_pri.h"
32 #include "los_task_pri.h"
33 #include "los_process_pri.h"
34 #include "los_hook.h"
35 #include "los_tick_pri.h"
36 #include "los_mp.h"
37
38 #define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF
39 #define PRIQUEUE_PRIOR0_BIT 0x80000000U
40 #define OS_SCHED_TIME_SLICES_MIN ((5000 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 5ms */
41 #define OS_SCHED_TIME_SLICES_MAX ((LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE)
42 #define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN)
43 #define OS_SCHED_READY_MAX 30
44 #define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */
45
46 STATIC HPFRunqueue g_schedHPF;
47
48 STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB);
49 STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB);
50 STATIC UINT64 HPFWaitTimeGet(LosTaskCB *taskCB);
51 STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks);
52 STATIC VOID HPFWake(LosTaskCB *resumedTask);
53 STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param);
54 STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param);
55 STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime);
56 STATIC VOID HPFYield(LosTaskCB *runTask);
57 STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB);
58 STATIC VOID HPFExit(LosTaskCB *taskCB);
59 STATIC UINT32 HPFSuspend(LosTaskCB *taskCB);
60 STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched);
61 STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB);
62 STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime);
63 STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2);
64 STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
65 STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);
66
67 const STATIC SchedOps g_priorityOps = {
68 .dequeue = HPFDequeue,
69 .enqueue = HPFEnqueue,
70 .waitTimeGet = HPFWaitTimeGet,
71 .wait = HPFWait,
72 .wake = HPFWake,
73 .schedParamModify = HPFSchedParamModify,
74 .schedParamGet = HPFSchedParamGet,
75 .delay = HPFDelay,
76 .yield = HPFYield,
77 .start = HPFStartToRun,
78 .exit = HPFExit,
79 .suspend = HPFSuspend,
80 .resume = HPFResume,
81 .deadlineGet = HPFTimeSliceGet,
82 .timeSliceUpdate = HPFTimeSliceUpdate,
83 .schedParamCompare = HPFParamCompare,
84 .priorityInheritance = HPFPriorityInheritance,
85 .priorityRestore = HPFPriorityRestore,
86 };
87
HPFTimeSliceUpdate(SchedRunqueue * rq,LosTaskCB * taskCB,UINT64 currTime)88 STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime)
89 {
90 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
91 LOS_ASSERT(currTime >= taskCB->startTime);
92
93 INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime);
94
95 LOS_ASSERT(incTime >= 0);
96
97 if (sched->policy == LOS_SCHED_RR) {
98 taskCB->timeSlice -= incTime;
99 #ifdef LOSCFG_SCHED_HPF_DEBUG
100 taskCB->schedStat.timeSliceRealTime += incTime;
101 #endif
102 }
103 #ifdef LOSCFG_KERNEL_SCHED_PLIMIT
104 OsSchedLimitUpdateRuntime(taskCB, currTime, incTime);
105 #endif
106 taskCB->irqUsedTime = 0;
107 taskCB->startTime = currTime;
108 if (taskCB->timeSlice <= OS_TIME_SLICE_MIN) {
109 rq->schedFlag |= INT_PEND_RESCH;
110 }
111
112 #ifdef LOSCFG_SCHED_HPF_DEBUG
113 taskCB->schedStat.allRuntime += incTime;
114 #endif
115 }
116
HPFTimeSliceGet(const LosTaskCB * taskCB)117 STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB)
118 {
119 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
120 INT32 timeSlice = taskCB->timeSlice;
121
122 timeSlice = (timeSlice <= OS_TIME_SLICE_MIN) ? sched->initTimeSlice : timeSlice;
123 return (taskCB->startTime + timeSlice);
124 }
125
TimeSliceCalculate(HPFRunqueue * rq,UINT16 basePrio,UINT16 priority)126 STATIC INLINE UINT32 TimeSliceCalculate(HPFRunqueue *rq, UINT16 basePrio, UINT16 priority)
127 {
128 UINT32 time;
129 UINT32 readyTasks;
130
131 HPFQueue *queueList = &rq->queueList[basePrio];
132 readyTasks = queueList->readyTasks[priority];
133 if (readyTasks > OS_SCHED_READY_MAX) {
134 return OS_SCHED_TIME_SLICES_MIN;
135 }
136 time = ((OS_SCHED_READY_MAX - readyTasks) * OS_SCHED_TIME_SLICES_DIFF) / OS_SCHED_READY_MAX;
137 return (time + OS_SCHED_TIME_SLICES_MIN);
138 }
139
PriQueHeadInsert(HPFRunqueue * rq,UINT32 basePrio,LOS_DL_LIST * priQue,UINT32 priority)140 STATIC INLINE VOID PriQueHeadInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority)
141 {
142 HPFQueue *queueList = &rq->queueList[basePrio];
143 LOS_DL_LIST *priQueList = &queueList->priQueList[0];
144 UINT32 *bitmap = &queueList->queueBitmap;
145
146 /*
147 * Task control blocks are inited as zero. And when task is deleted,
148 * and at the same time would be deleted from priority queue or
149 * other lists, task pend node will restored as zero.
150 */
151 LOS_ASSERT(priQue->pstNext == NULL);
152
153 if (*bitmap == 0) {
154 rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio;
155 }
156
157 if (LOS_ListEmpty(&priQueList[priority])) {
158 *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority;
159 }
160
161 LOS_ListHeadInsert(&priQueList[priority], priQue);
162 queueList->readyTasks[priority]++;
163 }
164
PriQueTailInsert(HPFRunqueue * rq,UINT32 basePrio,LOS_DL_LIST * priQue,UINT32 priority)165 STATIC INLINE VOID PriQueTailInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority)
166 {
167 HPFQueue *queueList = &rq->queueList[basePrio];
168 LOS_DL_LIST *priQueList = &queueList->priQueList[0];
169 UINT32 *bitmap = &queueList->queueBitmap;
170
171 /*
172 * Task control blocks are inited as zero. And when task is deleted,
173 * and at the same time would be deleted from priority queue or
174 * other lists, task pend node will restored as zero.
175 */
176 LOS_ASSERT(priQue->pstNext == NULL);
177
178 if (*bitmap == 0) {
179 rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio;
180 }
181
182 if (LOS_ListEmpty(&priQueList[priority])) {
183 *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority;
184 }
185
186 LOS_ListTailInsert(&priQueList[priority], priQue);
187 queueList->readyTasks[priority]++;
188 }
189
PriQueDelete(HPFRunqueue * rq,UINT32 basePrio,LOS_DL_LIST * priQue,UINT32 priority)190 STATIC INLINE VOID PriQueDelete(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority)
191 {
192 HPFQueue *queueList = &rq->queueList[basePrio];
193 LOS_DL_LIST *priQueList = &queueList->priQueList[0];
194 UINT32 *bitmap = &queueList->queueBitmap;
195
196 LOS_ListDelete(priQue);
197 queueList->readyTasks[priority]--;
198 if (LOS_ListEmpty(&priQueList[priority])) {
199 *bitmap &= ~(PRIQUEUE_PRIOR0_BIT >> priority);
200 }
201
202 if (*bitmap == 0) {
203 rq->queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> basePrio);
204 }
205 }
206
PriQueInsert(HPFRunqueue * rq,LosTaskCB * taskCB)207 STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB)
208 {
209 LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY));
210 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
211
212 switch (sched->policy) {
213 case LOS_SCHED_RR: {
214 if (taskCB->timeSlice > OS_TIME_SLICE_MIN) {
215 PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
216 } else {
217 sched->initTimeSlice = TimeSliceCalculate(rq, sched->basePrio, sched->priority);
218 taskCB->timeSlice = sched->initTimeSlice;
219 PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
220 #ifdef LOSCFG_SCHED_HPF_DEBUG
221 taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime;
222 taskCB->schedStat.timeSliceCount++;
223 #endif
224 }
225 break;
226 }
227 case LOS_SCHED_FIFO: {
228 /* The time slice of FIFO is always greater than 0 unless the yield is called */
229 if ((taskCB->timeSlice > OS_TIME_SLICE_MIN) && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
230 PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
231 } else {
232 sched->initTimeSlice = OS_SCHED_FIFO_TIMEOUT;
233 taskCB->timeSlice = sched->initTimeSlice;
234 PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
235 }
236 break;
237 }
238 default:
239 LOS_ASSERT(0);
240 break;
241 }
242
243 taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED;
244 taskCB->taskStatus |= OS_TASK_STATUS_READY;
245 }
246
HPFEnqueue(SchedRunqueue * rq,LosTaskCB * taskCB)247 STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB)
248 {
249 #ifdef LOSCFG_SCHED_HPF_DEBUG
250 if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
251 taskCB->startTime = OsGetCurrSchedTimeCycle();
252 }
253 #endif
254 PriQueInsert(rq->hpfRunqueue, taskCB);
255 }
256
HPFDequeue(SchedRunqueue * rq,LosTaskCB * taskCB)257 STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB)
258 {
259 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
260
261 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
262 PriQueDelete(rq->hpfRunqueue, sched->basePrio, &taskCB->pendList, sched->priority);
263 taskCB->taskStatus &= ~OS_TASK_STATUS_READY;
264 }
265 }
266
HPFStartToRun(SchedRunqueue * rq,LosTaskCB * taskCB)267 STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB)
268 {
269 HPFDequeue(rq, taskCB);
270 }
271
HPFExit(LosTaskCB * taskCB)272 STATIC VOID HPFExit(LosTaskCB *taskCB)
273 {
274 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
275 HPFDequeue(OsSchedRunqueue(), taskCB);
276 } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) {
277 LOS_ListDelete(&taskCB->pendList);
278 taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING;
279 }
280
281 if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) {
282 OsSchedTimeoutQueueDelete(taskCB);
283 taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME);
284 }
285 }
286
HPFYield(LosTaskCB * runTask)287 STATIC VOID HPFYield(LosTaskCB *runTask)
288 {
289 SchedRunqueue *rq = OsSchedRunqueue();
290 runTask->timeSlice = 0;
291
292 runTask->startTime = OsGetCurrSchedTimeCycle();
293 HPFEnqueue(rq, runTask);
294 OsSchedResched();
295 }
296
HPFDelay(LosTaskCB * runTask,UINT64 waitTime)297 STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime)
298 {
299 runTask->taskStatus |= OS_TASK_STATUS_DELAY;
300 runTask->waitTime = waitTime;
301
302 OsSchedResched();
303 return LOS_OK;
304 }
305
HPFWaitTimeGet(LosTaskCB * taskCB)306 STATIC UINT64 HPFWaitTimeGet(LosTaskCB *taskCB)
307 {
308 taskCB->waitTime += taskCB->startTime;
309 return taskCB->waitTime;
310 }
311
HPFWait(LosTaskCB * runTask,LOS_DL_LIST * list,UINT32 ticks)312 STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks)
313 {
314 runTask->taskStatus |= OS_TASK_STATUS_PENDING;
315 LOS_ListTailInsert(list, &runTask->pendList);
316
317 if (ticks != LOS_WAIT_FOREVER) {
318 runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME;
319 runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks);
320 }
321
322 if (OsPreemptableInSched()) {
323 OsSchedResched();
324 if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {
325 runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;
326 return LOS_ERRNO_TSK_TIMEOUT;
327 }
328 }
329
330 return LOS_OK;
331 }
332
HPFWake(LosTaskCB * resumedTask)333 STATIC VOID HPFWake(LosTaskCB *resumedTask)
334 {
335 LOS_ListDelete(&resumedTask->pendList);
336 resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING;
337
338 if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) {
339 OsSchedTimeoutQueueDelete(resumedTask);
340 resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;
341 }
342
343 if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) {
344 #ifdef LOSCFG_SCHED_HPF_DEBUG
345 resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime;
346 resumedTask->schedStat.pendCount++;
347 #endif
348 HPFEnqueue(OsSchedRunqueue(), resumedTask);
349 }
350 }
351
BasePriorityModify(SchedRunqueue * rq,LosTaskCB * taskCB,UINT16 priority)352 STATIC BOOL BasePriorityModify(SchedRunqueue *rq, LosTaskCB *taskCB, UINT16 priority)
353 {
354 LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB);
355 BOOL needSched = FALSE;
356
357 LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {
358 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
359 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
360 taskCB->ops->dequeue(rq, taskCB);
361 sched->basePrio = priority;
362 taskCB->ops->enqueue(rq, taskCB);
363 } else {
364 sched->basePrio = priority;
365 }
366 if (taskCB->taskStatus & (OS_TASK_STATUS_READY | OS_TASK_STATUS_RUNNING)) {
367 needSched = TRUE;
368 }
369 }
370
371 return needSched;
372 }
373
HPFSchedParamModify(LosTaskCB * taskCB,const SchedParam * param)374 STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param)
375 {
376 SchedRunqueue *rq = OsSchedRunqueue();
377 BOOL needSched = FALSE;
378 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
379
380 if (sched->policy != param->policy) {
381 sched->policy = param->policy;
382 taskCB->timeSlice = 0;
383 }
384
385 if (sched->basePrio != param->basePrio) {
386 needSched = BasePriorityModify(rq, taskCB, param->basePrio);
387 }
388
389 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
390 HPFDequeue(rq, taskCB);
391 sched->priority = param->priority;
392 HPFEnqueue(rq, taskCB);
393 return TRUE;
394 }
395
396 sched->priority = param->priority;
397 OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, sched->priority);
398 if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {
399 HPFEnqueue(rq, taskCB);
400 return TRUE;
401 }
402
403 if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
404 return TRUE;
405 }
406
407 return needSched;
408 }
409
HPFSchedParamGet(const LosTaskCB * taskCB,SchedParam * param)410 STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param)
411 {
412 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
413 param->policy = sched->policy;
414 param->basePrio = sched->basePrio;
415 param->priority = sched->priority;
416 param->timeSlice = sched->initTimeSlice;
417 return LOS_OK;
418 }
419
HPFSuspend(LosTaskCB * taskCB)420 STATIC UINT32 HPFSuspend(LosTaskCB *taskCB)
421 {
422 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
423 HPFDequeue(OsSchedRunqueue(), taskCB);
424 }
425
426 SchedTaskFreeze(taskCB);
427
428 taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED;
429 OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB);
430 if (taskCB == OsCurrTaskGet()) {
431 OsSchedResched();
432 }
433 return LOS_OK;
434 }
435
HPFResume(LosTaskCB * taskCB,BOOL * needSched)436 STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched)
437 {
438 *needSched = FALSE;
439
440 SchedTaskUnfreeze(taskCB);
441
442 taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED;
443 if (!OsTaskIsBlocked(taskCB)) {
444 HPFEnqueue(OsSchedRunqueue(), taskCB);
445 *needSched = TRUE;
446 }
447
448 return LOS_OK;
449 }
450
HPFParamCompare(const SchedPolicy * sp1,const SchedPolicy * sp2)451 STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2)
452 {
453 SchedHPF *param1 = (SchedHPF *)sp1;
454 SchedHPF *param2 = (SchedHPF *)sp2;
455
456 if (param1->basePrio != param2->basePrio) {
457 return (param1->basePrio - param2->basePrio);
458 }
459
460 return (param1->priority - param2->priority);
461 }
462
HPFPriorityInheritance(LosTaskCB * owner,const SchedParam * param)463 STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param)
464 {
465 SchedHPF *sp = (SchedHPF *)&owner->sp;
466
467 if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) {
468 return;
469 }
470
471 if (sp->priority <= param->priority) {
472 return;
473 }
474
475 LOS_BitmapSet(&sp->priBitmap, sp->priority);
476 sp->priority = param->priority;
477 }
478
HPFPriorityRestore(LosTaskCB * owner,const LOS_DL_LIST * list,const SchedParam * param)479 STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param)
480 {
481 UINT16 priority;
482 LosTaskCB *pendedTask = NULL;
483
484 if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) {
485 return;
486 }
487
488 SchedHPF *sp = (SchedHPF *)&owner->sp;
489 if (sp->priority < param->priority) {
490 if (LOS_HighBitGet(sp->priBitmap) != param->priority) {
491 LOS_BitmapClr(&sp->priBitmap, param->priority);
492 }
493 return;
494 }
495
496 if (sp->priBitmap == 0) {
497 return;
498 }
499
500 if ((list != NULL) && !LOS_ListEmpty((LOS_DL_LIST *)list)) {
501 priority = LOS_HighBitGet(sp->priBitmap);
502 LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) {
503 SchedHPF *pendSp = (SchedHPF *)&pendedTask->sp;
504 if ((pendedTask->ops == owner->ops) && (priority != pendSp->priority)) {
505 LOS_BitmapClr(&sp->priBitmap, pendSp->priority);
506 }
507 }
508 }
509
510 priority = LOS_LowBitGet(sp->priBitmap);
511 if (priority != LOS_INVALID_BIT_INDEX) {
512 LOS_BitmapClr(&sp->priBitmap, priority);
513 sp->priority = priority;
514 }
515 }
516
HPFTaskSchedParamInit(LosTaskCB * taskCB,UINT16 policy,const SchedParam * parentParam,const LosSchedParam * param)517 VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
518 const SchedParam *parentParam,
519 const LosSchedParam *param)
520 {
521 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
522
523 sched->policy = policy;
524 if (param != NULL) {
525 sched->priority = param->priority;
526 } else {
527 sched->priority = parentParam->priority;
528 }
529 sched->basePrio = parentParam->basePrio;
530
531 sched->initTimeSlice = 0;
532 taskCB->timeSlice = sched->initTimeSlice;
533 taskCB->ops = &g_priorityOps;
534 }
535
HPFProcessDefaultSchedParamGet(SchedParam * param)536 VOID HPFProcessDefaultSchedParamGet(SchedParam *param)
537 {
538 param->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST;
539 }
540
HPFSchedPolicyInit(SchedRunqueue * rq)541 VOID HPFSchedPolicyInit(SchedRunqueue *rq)
542 {
543 if (ArchCurrCpuid() > 0) {
544 rq->hpfRunqueue = &g_schedHPF;
545 return;
546 }
547
548 for (UINT16 index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) {
549 HPFQueue *queueList = &g_schedHPF.queueList[index];
550 LOS_DL_LIST *priQue = &queueList->priQueList[0];
551 for (UINT16 prio = 0; prio < OS_PRIORITY_QUEUE_NUM; prio++) {
552 LOS_ListInit(&priQue[prio]);
553 }
554 }
555
556 rq->hpfRunqueue = &g_schedHPF;
557 }
558