• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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