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 #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 UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks);
51 STATIC VOID HPFWake(LosTaskCB *resumedTask);
52 STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param);
53 STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param);
54 STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime);
55 STATIC VOID HPFYield(LosTaskCB *runTask);
56 STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB);
57 STATIC VOID HPFExit(LosTaskCB *taskCB);
58 STATIC UINT32 HPFSuspend(LosTaskCB *taskCB);
59 STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched);
60 STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB);
61 STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime);
62 STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2);
63 STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
64 STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);
65
66 const STATIC SchedOps g_priorityOps = {
67 .dequeue = HPFDequeue,
68 .enqueue = HPFEnqueue,
69 .wait = HPFWait,
70 .wake = HPFWake,
71 .schedParamModify = HPFSchedParamModify,
72 .schedParamGet = HPFSchedParamGet,
73 .delay = HPFDelay,
74 .yield = HPFYield,
75 .start = HPFStartToRun,
76 .exit = HPFExit,
77 .suspend = HPFSuspend,
78 .resume = HPFResume,
79 .deadlineGet = HPFTimeSliceGet,
80 .timeSliceUpdate = HPFTimeSliceUpdate,
81 .schedParamCompare = HPFParamCompare,
82 .priorityInheritance = HPFPriorityInheritance,
83 .priorityRestore = HPFPriorityRestore,
84 };
85
HPFTimeSliceUpdate(SchedRunqueue * rq,LosTaskCB * taskCB,UINT64 currTime)86 STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime)
87 {
88 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
89 LOS_ASSERT(currTime >= taskCB->startTime);
90
91 INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime);
92
93 LOS_ASSERT(incTime >= 0);
94
95 if (sched->policy == LOS_SCHED_RR) {
96 taskCB->timeSlice -= incTime;
97 #ifdef LOSCFG_SCHED_DEBUG
98 taskCB->schedStat.timeSliceRealTime += incTime;
99 #endif
100 }
101 taskCB->irqUsedTime = 0;
102 taskCB->startTime = currTime;
103 if (taskCB->timeSlice <= OS_TIME_SLICE_MIN) {
104 rq->schedFlag |= INT_PEND_RESCH;
105 }
106
107 #ifdef LOSCFG_SCHED_DEBUG
108 taskCB->schedStat.allRuntime += incTime;
109 #endif
110 }
111
HPFTimeSliceGet(const LosTaskCB * taskCB)112 STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB)
113 {
114 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
115 INT32 timeSlice = taskCB->timeSlice;
116
117 timeSlice = (timeSlice <= OS_TIME_SLICE_MIN) ? sched->initTimeSlice : timeSlice;
118 return (taskCB->startTime + timeSlice);
119 }
120
TimeSliceCalculate(HPFRunqueue * rq,UINT16 basePrio,UINT16 priority)121 STATIC INLINE UINT32 TimeSliceCalculate(HPFRunqueue *rq, UINT16 basePrio, UINT16 priority)
122 {
123 UINT32 time;
124 UINT32 readyTasks;
125
126 HPFQueue *queueList = &rq->queueList[basePrio];
127 readyTasks = queueList->readyTasks[priority];
128 if (readyTasks > OS_SCHED_READY_MAX) {
129 return OS_SCHED_TIME_SLICES_MIN;
130 }
131 time = ((OS_SCHED_READY_MAX - readyTasks) * OS_SCHED_TIME_SLICES_DIFF) / OS_SCHED_READY_MAX;
132 return (time + OS_SCHED_TIME_SLICES_MIN);
133 }
134
PriQueHeadInsert(HPFRunqueue * rq,UINT32 basePrio,LOS_DL_LIST * priQue,UINT32 priority)135 STATIC INLINE VOID PriQueHeadInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority)
136 {
137 HPFQueue *queueList = &rq->queueList[basePrio];
138 LOS_DL_LIST *priQueList = &queueList->priQueList[0];
139 UINT32 *bitmap = &queueList->queueBitmap;
140
141 /*
142 * Task control blocks are inited as zero. And when task is deleted,
143 * and at the same time would be deleted from priority queue or
144 * other lists, task pend node will restored as zero.
145 */
146 LOS_ASSERT(priQue->pstNext == NULL);
147
148 if (*bitmap == 0) {
149 rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio;
150 }
151
152 if (LOS_ListEmpty(&priQueList[priority])) {
153 *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority;
154 }
155
156 LOS_ListHeadInsert(&priQueList[priority], priQue);
157 queueList->readyTasks[priority]++;
158 }
159
PriQueTailInsert(HPFRunqueue * rq,UINT32 basePrio,LOS_DL_LIST * priQue,UINT32 priority)160 STATIC INLINE VOID PriQueTailInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority)
161 {
162 HPFQueue *queueList = &rq->queueList[basePrio];
163 LOS_DL_LIST *priQueList = &queueList->priQueList[0];
164 UINT32 *bitmap = &queueList->queueBitmap;
165
166 /*
167 * Task control blocks are inited as zero. And when task is deleted,
168 * and at the same time would be deleted from priority queue or
169 * other lists, task pend node will restored as zero.
170 */
171 LOS_ASSERT(priQue->pstNext == NULL);
172
173 if (*bitmap == 0) {
174 rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio;
175 }
176
177 if (LOS_ListEmpty(&priQueList[priority])) {
178 *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority;
179 }
180
181 LOS_ListTailInsert(&priQueList[priority], priQue);
182 queueList->readyTasks[priority]++;
183 }
184
PriQueDelete(HPFRunqueue * rq,UINT32 basePrio,LOS_DL_LIST * priQue,UINT32 priority)185 STATIC INLINE VOID PriQueDelete(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority)
186 {
187 HPFQueue *queueList = &rq->queueList[basePrio];
188 LOS_DL_LIST *priQueList = &queueList->priQueList[0];
189 UINT32 *bitmap = &queueList->queueBitmap;
190
191 LOS_ListDelete(priQue);
192 queueList->readyTasks[priority]--;
193 if (LOS_ListEmpty(&priQueList[priority])) {
194 *bitmap &= ~(PRIQUEUE_PRIOR0_BIT >> priority);
195 }
196
197 if (*bitmap == 0) {
198 rq->queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> basePrio);
199 }
200 }
201
PriQueInsert(HPFRunqueue * rq,LosTaskCB * taskCB)202 STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB)
203 {
204 LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY));
205 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
206
207 switch (sched->policy) {
208 case LOS_SCHED_RR: {
209 if (taskCB->timeSlice > OS_TIME_SLICE_MIN) {
210 PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
211 } else {
212 sched->initTimeSlice = TimeSliceCalculate(rq, sched->basePrio, sched->priority);
213 taskCB->timeSlice = sched->initTimeSlice;
214 PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
215 #ifdef LOSCFG_SCHED_DEBUG
216 taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime;
217 taskCB->schedStat.timeSliceCount++;
218 #endif
219 }
220 break;
221 }
222 case LOS_SCHED_FIFO: {
223 /* The time slice of FIFO is always greater than 0 unless the yield is called */
224 if ((taskCB->timeSlice > OS_TIME_SLICE_MIN) && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
225 PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
226 } else {
227 sched->initTimeSlice = OS_SCHED_FIFO_TIMEOUT;
228 taskCB->timeSlice = sched->initTimeSlice;
229 PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
230 }
231 break;
232 }
233 default:
234 LOS_ASSERT(0);
235 break;
236 }
237
238 taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED;
239 taskCB->taskStatus |= OS_TASK_STATUS_READY;
240 }
241
HPFEnqueue(SchedRunqueue * rq,LosTaskCB * taskCB)242 STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB)
243 {
244 #ifdef LOSCFG_SCHED_DEBUG
245 if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
246 taskCB->startTime = OsGetCurrSchedTimeCycle();
247 }
248 #endif
249 PriQueInsert(rq->hpfRunqueue, taskCB);
250 }
251
HPFDequeue(SchedRunqueue * rq,LosTaskCB * taskCB)252 STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB)
253 {
254 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
255
256 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
257 PriQueDelete(rq->hpfRunqueue, sched->basePrio, &taskCB->pendList, sched->priority);
258 taskCB->taskStatus &= ~OS_TASK_STATUS_READY;
259 }
260 }
261
HPFStartToRun(SchedRunqueue * rq,LosTaskCB * taskCB)262 STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB)
263 {
264 HPFDequeue(rq, taskCB);
265 }
266
HPFExit(LosTaskCB * taskCB)267 STATIC VOID HPFExit(LosTaskCB *taskCB)
268 {
269 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
270 HPFDequeue(OsSchedRunqueue(), taskCB);
271 } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) {
272 LOS_ListDelete(&taskCB->pendList);
273 taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING;
274 }
275
276 if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) {
277 OsSchedTimeoutQueueDelete(taskCB);
278 taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME);
279 }
280 }
281
HPFYield(LosTaskCB * runTask)282 STATIC VOID HPFYield(LosTaskCB *runTask)
283 {
284 SchedRunqueue *rq = OsSchedRunqueue();
285 runTask->timeSlice = 0;
286
287 runTask->startTime = OsGetCurrSchedTimeCycle();
288 HPFEnqueue(rq, runTask);
289 OsSchedResched();
290 }
291
HPFDelay(LosTaskCB * runTask,UINT64 waitTime)292 STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime)
293 {
294 runTask->taskStatus |= OS_TASK_STATUS_DELAY;
295 runTask->waitTime = waitTime;
296
297 OsSchedResched();
298 return LOS_OK;
299 }
300
HPFWait(LosTaskCB * runTask,LOS_DL_LIST * list,UINT32 ticks)301 STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks)
302 {
303 runTask->taskStatus |= OS_TASK_STATUS_PENDING;
304 LOS_ListTailInsert(list, &runTask->pendList);
305
306 if (ticks != LOS_WAIT_FOREVER) {
307 runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME;
308 runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks);
309 }
310
311 if (OsPreemptableInSched()) {
312 OsSchedResched();
313 if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {
314 runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;
315 return LOS_ERRNO_TSK_TIMEOUT;
316 }
317 }
318
319 return LOS_OK;
320 }
321
HPFWake(LosTaskCB * resumedTask)322 STATIC VOID HPFWake(LosTaskCB *resumedTask)
323 {
324 LOS_ListDelete(&resumedTask->pendList);
325 resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING;
326
327 if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) {
328 OsSchedTimeoutQueueDelete(resumedTask);
329 resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;
330 }
331
332 if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) {
333 #ifdef LOSCFG_SCHED_DEBUG
334 resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime;
335 resumedTask->schedStat.pendCount++;
336 #endif
337 HPFEnqueue(OsSchedRunqueue(), resumedTask);
338 }
339 }
340
BasePriorityModify(SchedRunqueue * rq,LosTaskCB * taskCB,UINT16 priority)341 STATIC BOOL BasePriorityModify(SchedRunqueue *rq, LosTaskCB *taskCB, UINT16 priority)
342 {
343 LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
344 BOOL needSched = FALSE;
345
346 LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {
347 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
348 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
349 taskCB->ops->dequeue(rq, taskCB);
350 sched->basePrio = priority;
351 taskCB->ops->enqueue(rq, taskCB);
352 } else {
353 sched->basePrio = priority;
354 }
355 if (taskCB->taskStatus & (OS_TASK_STATUS_READY | OS_TASK_STATUS_RUNNING)) {
356 needSched = TRUE;
357 }
358 }
359
360 return needSched;
361 }
362
HPFSchedParamModify(LosTaskCB * taskCB,const SchedParam * param)363 STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param)
364 {
365 SchedRunqueue *rq = OsSchedRunqueue();
366 BOOL needSched = FALSE;
367 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
368
369 if (sched->policy != param->policy) {
370 sched->policy = param->policy;
371 taskCB->timeSlice = 0;
372 }
373
374 if (sched->basePrio != param->basePrio) {
375 needSched = BasePriorityModify(rq, taskCB, param->basePrio);
376 }
377
378 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
379 HPFDequeue(rq, taskCB);
380 sched->priority = param->priority;
381 HPFEnqueue(rq, taskCB);
382 return TRUE;
383 }
384
385 sched->priority = param->priority;
386 OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, sched->priority);
387 if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {
388 HPFEnqueue(rq, taskCB);
389 return TRUE;
390 }
391
392 if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
393 return TRUE;
394 }
395
396 return needSched;
397 }
398
HPFSchedParamGet(const LosTaskCB * taskCB,SchedParam * param)399 STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param)
400 {
401 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
402 param->policy = sched->policy;
403 param->basePrio = sched->basePrio;
404 param->priority = sched->priority;
405 param->timeSlice = sched->initTimeSlice;
406 return LOS_OK;
407 }
408
HPFSuspend(LosTaskCB * taskCB)409 STATIC UINT32 HPFSuspend(LosTaskCB *taskCB)
410 {
411 if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
412 HPFDequeue(OsSchedRunqueue(), taskCB);
413 }
414
415 SchedTaskFreeze(taskCB);
416
417 taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED;
418 OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB);
419 if (taskCB == OsCurrTaskGet()) {
420 OsSchedResched();
421 }
422 return LOS_OK;
423 }
424
HPFResume(LosTaskCB * taskCB,BOOL * needSched)425 STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched)
426 {
427 *needSched = FALSE;
428
429 SchedTaskUnfreeze(taskCB);
430
431 taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED;
432 if (!OsTaskIsBlocked(taskCB)) {
433 HPFEnqueue(OsSchedRunqueue(), taskCB);
434 *needSched = TRUE;
435 }
436
437 return LOS_OK;
438 }
439
HPFParamCompare(const SchedPolicy * sp1,const SchedPolicy * sp2)440 STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2)
441 {
442 SchedHPF *param1 = (SchedHPF *)sp1;
443 SchedHPF *param2 = (SchedHPF *)sp2;
444
445 if (param1->basePrio != param2->basePrio) {
446 return (param1->basePrio - param2->basePrio);
447 }
448
449 return (param1->priority - param2->priority);
450 }
451
HPFPriorityInheritance(LosTaskCB * owner,const SchedParam * param)452 STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param)
453 {
454 SchedHPF *sp = (SchedHPF *)&owner->sp;
455
456 if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) {
457 return;
458 }
459
460 if (sp->priority <= param->priority) {
461 return;
462 }
463
464 LOS_BitmapSet(&sp->priBitmap, sp->priority);
465 sp->priority = param->priority;
466 }
467
HPFPriorityRestore(LosTaskCB * owner,const LOS_DL_LIST * list,const SchedParam * param)468 STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param)
469 {
470 UINT16 priority;
471 LosTaskCB *pendedTask = NULL;
472
473 if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) {
474 return;
475 }
476
477 SchedHPF *sp = (SchedHPF *)&owner->sp;
478 if (sp->priority < param->priority) {
479 if (LOS_HighBitGet(sp->priBitmap) != param->priority) {
480 LOS_BitmapClr(&sp->priBitmap, param->priority);
481 }
482 return;
483 }
484
485 if (sp->priBitmap == 0) {
486 return;
487 }
488
489 if ((list != NULL) && !LOS_ListEmpty((LOS_DL_LIST *)list)) {
490 priority = LOS_HighBitGet(sp->priBitmap);
491 LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) {
492 SchedHPF *pendSp = (SchedHPF *)&pendedTask->sp;
493 if ((pendedTask->ops == owner->ops) && (priority != pendSp->priority)) {
494 LOS_BitmapClr(&sp->priBitmap, pendSp->priority);
495 }
496 }
497 }
498
499 priority = LOS_LowBitGet(sp->priBitmap);
500 if (priority != LOS_INVALID_BIT_INDEX) {
501 LOS_BitmapClr(&sp->priBitmap, priority);
502 sp->priority = priority;
503 }
504 }
505
HPFTaskSchedParamInit(LosTaskCB * taskCB,UINT16 policy,const SchedParam * parentParam,const TSK_INIT_PARAM_S * param)506 VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
507 const SchedParam *parentParam,
508 const TSK_INIT_PARAM_S *param)
509 {
510 SchedHPF *sched = (SchedHPF *)&taskCB->sp;
511
512 sched->policy = policy;
513 if (param != NULL) {
514 sched->priority = param->usTaskPrio;
515 } else {
516 sched->priority = parentParam->priority;
517 }
518 sched->basePrio = parentParam->basePrio;
519
520 sched->initTimeSlice = 0;
521 taskCB->timeSlice = sched->initTimeSlice;
522 taskCB->ops = &g_priorityOps;
523 }
524
HPFProcessDefaultSchedParamGet(SchedParam * param)525 VOID HPFProcessDefaultSchedParamGet(SchedParam *param)
526 {
527 param->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST;
528 }
529
HPFSchedPolicyInit(SchedRunqueue * rq)530 VOID HPFSchedPolicyInit(SchedRunqueue *rq)
531 {
532 if (ArchCurrCpuid() > 0) {
533 rq->hpfRunqueue = &g_schedHPF;
534 return;
535 }
536
537 for (UINT16 index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) {
538 HPFQueue *queueList = &g_schedHPF.queueList[index];
539 LOS_DL_LIST *priQue = &queueList->priQueList[0];
540 for (UINT16 prio = 0; prio < OS_PRIORITY_QUEUE_NUM; prio++) {
541 LOS_ListInit(&priQue[prio]);
542 }
543 }
544
545 rq->hpfRunqueue = &g_schedHPF;
546 }
547