10d163575Sopenharmony_ci/* 20d163575Sopenharmony_ci * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. 30d163575Sopenharmony_ci * 40d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 50d163575Sopenharmony_ci * are permitted provided that the following conditions are met: 60d163575Sopenharmony_ci * 70d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 80d163575Sopenharmony_ci * conditions and the following disclaimer. 90d163575Sopenharmony_ci * 100d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 110d163575Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 120d163575Sopenharmony_ci * provided with the distribution. 130d163575Sopenharmony_ci * 140d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 150d163575Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 160d163575Sopenharmony_ci * permission. 170d163575Sopenharmony_ci * 180d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 190d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 200d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 210d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 220d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 230d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 240d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 250d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 260d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 270d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 280d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 290d163575Sopenharmony_ci */ 300d163575Sopenharmony_ci 310d163575Sopenharmony_ci#include "los_sched_pri.h" 320d163575Sopenharmony_ci#include "los_task_pri.h" 330d163575Sopenharmony_ci#include "los_process_pri.h" 340d163575Sopenharmony_ci#include "los_hook.h" 350d163575Sopenharmony_ci#include "los_tick_pri.h" 360d163575Sopenharmony_ci#include "los_sys_pri.h" 370d163575Sopenharmony_ci 380d163575Sopenharmony_ciSTATIC EDFRunqueue g_schedEDF; 390d163575Sopenharmony_ci 400d163575Sopenharmony_ciSTATIC VOID EDFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB); 410d163575Sopenharmony_ciSTATIC VOID EDFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB); 420d163575Sopenharmony_ciSTATIC UINT64 EDFWaitTimeGet(LosTaskCB *taskCB); 430d163575Sopenharmony_ciSTATIC UINT32 EDFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks); 440d163575Sopenharmony_ciSTATIC VOID EDFWake(LosTaskCB *resumedTask); 450d163575Sopenharmony_ciSTATIC BOOL EDFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param); 460d163575Sopenharmony_ciSTATIC UINT32 EDFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param); 470d163575Sopenharmony_ciSTATIC UINT32 EDFDelay(LosTaskCB *runTask, UINT64 waitTime); 480d163575Sopenharmony_ciSTATIC VOID EDFYield(LosTaskCB *runTask); 490d163575Sopenharmony_ciSTATIC VOID EDFExit(LosTaskCB *taskCB); 500d163575Sopenharmony_ciSTATIC UINT32 EDFSuspend(LosTaskCB *taskCB); 510d163575Sopenharmony_ciSTATIC UINT32 EDFResume(LosTaskCB *taskCB, BOOL *needSched); 520d163575Sopenharmony_ciSTATIC UINT64 EDFTimeSliceGet(const LosTaskCB *taskCB); 530d163575Sopenharmony_ciSTATIC VOID EDFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); 540d163575Sopenharmony_ciSTATIC INT32 EDFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); 550d163575Sopenharmony_ciSTATIC VOID EDFPriorityInheritance(LosTaskCB *owner, const SchedParam *param); 560d163575Sopenharmony_ciSTATIC VOID EDFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); 570d163575Sopenharmony_ci 580d163575Sopenharmony_ciconst STATIC SchedOps g_deadlineOps = { 590d163575Sopenharmony_ci .dequeue = EDFDequeue, 600d163575Sopenharmony_ci .enqueue = EDFEnqueue, 610d163575Sopenharmony_ci .waitTimeGet = EDFWaitTimeGet, 620d163575Sopenharmony_ci .wait = EDFWait, 630d163575Sopenharmony_ci .wake = EDFWake, 640d163575Sopenharmony_ci .schedParamModify = EDFSchedParamModify, 650d163575Sopenharmony_ci .schedParamGet = EDFSchedParamGet, 660d163575Sopenharmony_ci .delay = EDFDelay, 670d163575Sopenharmony_ci .yield = EDFYield, 680d163575Sopenharmony_ci .start = EDFDequeue, 690d163575Sopenharmony_ci .exit = EDFExit, 700d163575Sopenharmony_ci .suspend = EDFSuspend, 710d163575Sopenharmony_ci .resume = EDFResume, 720d163575Sopenharmony_ci .deadlineGet = EDFTimeSliceGet, 730d163575Sopenharmony_ci .timeSliceUpdate = EDFTimeSliceUpdate, 740d163575Sopenharmony_ci .schedParamCompare = EDFParamCompare, 750d163575Sopenharmony_ci .priorityInheritance = EDFPriorityInheritance, 760d163575Sopenharmony_ci .priorityRestore = EDFPriorityRestore, 770d163575Sopenharmony_ci}; 780d163575Sopenharmony_ci 790d163575Sopenharmony_ciSTATIC VOID EDFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime) 800d163575Sopenharmony_ci{ 810d163575Sopenharmony_ci SchedEDF *sched = (SchedEDF *)&taskCB->sp; 820d163575Sopenharmony_ci 830d163575Sopenharmony_ci LOS_ASSERT(currTime >= taskCB->startTime); 840d163575Sopenharmony_ci 850d163575Sopenharmony_ci if (taskCB->timeSlice <= 0) { 860d163575Sopenharmony_ci taskCB->irqUsedTime = 0; 870d163575Sopenharmony_ci return; 880d163575Sopenharmony_ci } 890d163575Sopenharmony_ci 900d163575Sopenharmony_ci INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime); 910d163575Sopenharmony_ci LOS_ASSERT(incTime >= 0); 920d163575Sopenharmony_ci 930d163575Sopenharmony_ci#ifdef LOSCFG_SCHED_EDF_DEBUG 940d163575Sopenharmony_ci taskCB->schedStat.timeSliceRealTime += incTime; 950d163575Sopenharmony_ci taskCB->schedStat.allRuntime += (currTime - taskCB->startTime); 960d163575Sopenharmony_ci#endif 970d163575Sopenharmony_ci 980d163575Sopenharmony_ci taskCB->timeSlice -= incTime; 990d163575Sopenharmony_ci taskCB->irqUsedTime = 0; 1000d163575Sopenharmony_ci taskCB->startTime = currTime; 1010d163575Sopenharmony_ci 1020d163575Sopenharmony_ci if ((sched->finishTime > currTime) && (taskCB->timeSlice > 0)) { 1030d163575Sopenharmony_ci return; 1040d163575Sopenharmony_ci } 1050d163575Sopenharmony_ci 1060d163575Sopenharmony_ci rq->schedFlag |= INT_PEND_RESCH; 1070d163575Sopenharmony_ci if (sched->finishTime <= currTime) { 1080d163575Sopenharmony_ci#ifdef LOSCFG_SCHED_EDF_DEBUG 1090d163575Sopenharmony_ci EDFDebugRecord((UINTPTR *)taskCB, sched->finishTime); 1100d163575Sopenharmony_ci#endif 1110d163575Sopenharmony_ci 1120d163575Sopenharmony_ci taskCB->timeSlice = 0; 1130d163575Sopenharmony_ci PrintExcInfo("EDF task %u is timeout, runTime: %d us period: %llu us\n", taskCB->taskID, 1140d163575Sopenharmony_ci (INT32)OS_SYS_CYCLE_TO_US((UINT64)sched->runTime), OS_SYS_CYCLE_TO_US(sched->period)); 1150d163575Sopenharmony_ci } 1160d163575Sopenharmony_ci} 1170d163575Sopenharmony_ci 1180d163575Sopenharmony_ciSTATIC UINT64 EDFTimeSliceGet(const LosTaskCB *taskCB) 1190d163575Sopenharmony_ci{ 1200d163575Sopenharmony_ci SchedEDF *sched = (SchedEDF *)&taskCB->sp; 1210d163575Sopenharmony_ci UINT64 endTime = taskCB->startTime + taskCB->timeSlice; 1220d163575Sopenharmony_ci return (endTime > sched->finishTime) ? sched->finishTime : endTime; 1230d163575Sopenharmony_ci} 1240d163575Sopenharmony_ci 1250d163575Sopenharmony_ciSTATIC VOID DeadlineQueueInsert(EDFRunqueue *rq, LosTaskCB *taskCB) 1260d163575Sopenharmony_ci{ 1270d163575Sopenharmony_ci LOS_DL_LIST *root = &rq->root; 1280d163575Sopenharmony_ci if (LOS_ListEmpty(root)) { 1290d163575Sopenharmony_ci LOS_ListTailInsert(root, &taskCB->pendList); 1300d163575Sopenharmony_ci return; 1310d163575Sopenharmony_ci } 1320d163575Sopenharmony_ci 1330d163575Sopenharmony_ci LOS_DL_LIST *list = root->pstNext; 1340d163575Sopenharmony_ci do { 1350d163575Sopenharmony_ci LosTaskCB *readyTask = LOS_DL_LIST_ENTRY(list, LosTaskCB, pendList); 1360d163575Sopenharmony_ci if (EDFParamCompare(&readyTask->sp, &taskCB->sp) > 0) { 1370d163575Sopenharmony_ci LOS_ListHeadInsert(list, &taskCB->pendList); 1380d163575Sopenharmony_ci return; 1390d163575Sopenharmony_ci } 1400d163575Sopenharmony_ci list = list->pstNext; 1410d163575Sopenharmony_ci } while (list != root); 1420d163575Sopenharmony_ci 1430d163575Sopenharmony_ci LOS_ListHeadInsert(list, &taskCB->pendList); 1440d163575Sopenharmony_ci} 1450d163575Sopenharmony_ci 1460d163575Sopenharmony_ciSTATIC VOID EDFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) 1470d163575Sopenharmony_ci{ 1480d163575Sopenharmony_ci LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); 1490d163575Sopenharmony_ci 1500d163575Sopenharmony_ci EDFRunqueue *erq = rq->edfRunqueue; 1510d163575Sopenharmony_ci SchedEDF *sched = (SchedEDF *)&taskCB->sp; 1520d163575Sopenharmony_ci if (taskCB->timeSlice <= 0) { 1530d163575Sopenharmony_ci#ifdef LOSCFG_SCHED_EDF_DEBUG 1540d163575Sopenharmony_ci UINT64 oldFinish = sched->finishTime; 1550d163575Sopenharmony_ci#endif 1560d163575Sopenharmony_ci UINT64 currTime = OsGetCurrSchedTimeCycle(); 1570d163575Sopenharmony_ci if (sched->flags == EDF_INIT) { 1580d163575Sopenharmony_ci sched->finishTime = currTime; 1590d163575Sopenharmony_ci } else if (sched->flags != EDF_NEXT_PERIOD) { 1600d163575Sopenharmony_ci /* The start time of the next period */ 1610d163575Sopenharmony_ci sched->finishTime = (sched->finishTime - sched->deadline) + sched->period; 1620d163575Sopenharmony_ci } 1630d163575Sopenharmony_ci 1640d163575Sopenharmony_ci /* Calculate the start time of the next period */ 1650d163575Sopenharmony_ci while (1) { 1660d163575Sopenharmony_ci /* The deadline of the next period */ 1670d163575Sopenharmony_ci UINT64 finishTime = sched->finishTime + sched->deadline; 1680d163575Sopenharmony_ci if ((finishTime <= currTime) || ((sched->finishTime + sched->runTime) > finishTime)) { 1690d163575Sopenharmony_ci /* This period cannot meet the minimum running time, so it is migrated to the next period */ 1700d163575Sopenharmony_ci sched->finishTime += sched->period; 1710d163575Sopenharmony_ci continue; 1720d163575Sopenharmony_ci } 1730d163575Sopenharmony_ci break; 1740d163575Sopenharmony_ci } 1750d163575Sopenharmony_ci 1760d163575Sopenharmony_ci if (sched->finishTime > currTime) { 1770d163575Sopenharmony_ci /* Wait for the next period to start */ 1780d163575Sopenharmony_ci LOS_ListTailInsert(&erq->waitList, &taskCB->pendList); 1790d163575Sopenharmony_ci taskCB->waitTime = OS_SCHED_MAX_RESPONSE_TIME; 1800d163575Sopenharmony_ci if (!OsTaskIsRunning(taskCB)) { 1810d163575Sopenharmony_ci OsSchedTimeoutQueueAdd(taskCB, sched->finishTime); 1820d163575Sopenharmony_ci } 1830d163575Sopenharmony_ci#ifdef LOSCFG_SCHED_EDF_DEBUG 1840d163575Sopenharmony_ci if (oldFinish != sched->finishTime) { 1850d163575Sopenharmony_ci EDFDebugRecord((UINTPTR *)taskCB, oldFinish); 1860d163575Sopenharmony_ci taskCB->schedStat.allRuntime = 0; 1870d163575Sopenharmony_ci taskCB->schedStat.timeSliceRealTime = 0; 1880d163575Sopenharmony_ci taskCB->schedStat.pendTime = 0; 1890d163575Sopenharmony_ci } 1900d163575Sopenharmony_ci#endif 1910d163575Sopenharmony_ci taskCB->taskStatus |= OS_TASK_STATUS_PEND_TIME; 1920d163575Sopenharmony_ci sched->flags = EDF_NEXT_PERIOD; 1930d163575Sopenharmony_ci return; 1940d163575Sopenharmony_ci } 1950d163575Sopenharmony_ci 1960d163575Sopenharmony_ci sched->finishTime += sched->deadline; 1970d163575Sopenharmony_ci taskCB->timeSlice = sched->runTime; 1980d163575Sopenharmony_ci sched->flags = EDF_UNUSED; 1990d163575Sopenharmony_ci } 2000d163575Sopenharmony_ci 2010d163575Sopenharmony_ci DeadlineQueueInsert(erq, taskCB); 2020d163575Sopenharmony_ci taskCB->taskStatus &= ~(OS_TASK_STATUS_BLOCKED | OS_TASK_STATUS_TIMEOUT); 2030d163575Sopenharmony_ci taskCB->taskStatus |= OS_TASK_STATUS_READY; 2040d163575Sopenharmony_ci} 2050d163575Sopenharmony_ci 2060d163575Sopenharmony_ciSTATIC VOID EDFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB) 2070d163575Sopenharmony_ci{ 2080d163575Sopenharmony_ci (VOID)rq; 2090d163575Sopenharmony_ci LOS_ListDelete(&taskCB->pendList); 2100d163575Sopenharmony_ci taskCB->taskStatus &= ~OS_TASK_STATUS_READY; 2110d163575Sopenharmony_ci} 2120d163575Sopenharmony_ci 2130d163575Sopenharmony_ciSTATIC VOID EDFExit(LosTaskCB *taskCB) 2140d163575Sopenharmony_ci{ 2150d163575Sopenharmony_ci if (taskCB->taskStatus & OS_TASK_STATUS_READY) { 2160d163575Sopenharmony_ci EDFDequeue(OsSchedRunqueue(), taskCB); 2170d163575Sopenharmony_ci } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { 2180d163575Sopenharmony_ci LOS_ListDelete(&taskCB->pendList); 2190d163575Sopenharmony_ci taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; 2200d163575Sopenharmony_ci } 2210d163575Sopenharmony_ci if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { 2220d163575Sopenharmony_ci OsSchedTimeoutQueueDelete(taskCB); 2230d163575Sopenharmony_ci taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); 2240d163575Sopenharmony_ci } 2250d163575Sopenharmony_ci} 2260d163575Sopenharmony_ci 2270d163575Sopenharmony_ciSTATIC VOID EDFYield(LosTaskCB *runTask) 2280d163575Sopenharmony_ci{ 2290d163575Sopenharmony_ci SchedRunqueue *rq = OsSchedRunqueue(); 2300d163575Sopenharmony_ci runTask->timeSlice = 0; 2310d163575Sopenharmony_ci 2320d163575Sopenharmony_ci runTask->startTime = OsGetCurrSchedTimeCycle(); 2330d163575Sopenharmony_ci EDFEnqueue(rq, runTask); 2340d163575Sopenharmony_ci OsSchedResched(); 2350d163575Sopenharmony_ci} 2360d163575Sopenharmony_ci 2370d163575Sopenharmony_ciSTATIC UINT32 EDFDelay(LosTaskCB *runTask, UINT64 waitTime) 2380d163575Sopenharmony_ci{ 2390d163575Sopenharmony_ci runTask->taskStatus |= OS_TASK_STATUS_DELAY; 2400d163575Sopenharmony_ci runTask->waitTime = waitTime; 2410d163575Sopenharmony_ci OsSchedResched(); 2420d163575Sopenharmony_ci return LOS_OK; 2430d163575Sopenharmony_ci} 2440d163575Sopenharmony_ci 2450d163575Sopenharmony_ciSTATIC UINT64 EDFWaitTimeGet(LosTaskCB *taskCB) 2460d163575Sopenharmony_ci{ 2470d163575Sopenharmony_ci const SchedEDF *sched = (const SchedEDF *)&taskCB->sp; 2480d163575Sopenharmony_ci if (sched->flags != EDF_WAIT_FOREVER) { 2490d163575Sopenharmony_ci taskCB->waitTime += taskCB->startTime; 2500d163575Sopenharmony_ci } 2510d163575Sopenharmony_ci return (taskCB->waitTime >= sched->finishTime) ? sched->finishTime : taskCB->waitTime; 2520d163575Sopenharmony_ci} 2530d163575Sopenharmony_ci 2540d163575Sopenharmony_ciSTATIC UINT32 EDFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks) 2550d163575Sopenharmony_ci{ 2560d163575Sopenharmony_ci SchedEDF *sched = (SchedEDF *)&runTask->sp; 2570d163575Sopenharmony_ci runTask->taskStatus |= (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME); 2580d163575Sopenharmony_ci LOS_ListTailInsert(list, &runTask->pendList); 2590d163575Sopenharmony_ci 2600d163575Sopenharmony_ci if (ticks != LOS_WAIT_FOREVER) { 2610d163575Sopenharmony_ci runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks); 2620d163575Sopenharmony_ci } else { 2630d163575Sopenharmony_ci sched->flags = EDF_WAIT_FOREVER; 2640d163575Sopenharmony_ci runTask->waitTime = OS_SCHED_MAX_RESPONSE_TIME; 2650d163575Sopenharmony_ci } 2660d163575Sopenharmony_ci 2670d163575Sopenharmony_ci if (OsPreemptableInSched()) { 2680d163575Sopenharmony_ci OsSchedResched(); 2690d163575Sopenharmony_ci if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { 2700d163575Sopenharmony_ci runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; 2710d163575Sopenharmony_ci return LOS_ERRNO_TSK_TIMEOUT; 2720d163575Sopenharmony_ci } 2730d163575Sopenharmony_ci } 2740d163575Sopenharmony_ci 2750d163575Sopenharmony_ci return LOS_OK; 2760d163575Sopenharmony_ci} 2770d163575Sopenharmony_ci 2780d163575Sopenharmony_ciSTATIC VOID EDFWake(LosTaskCB *resumedTask) 2790d163575Sopenharmony_ci{ 2800d163575Sopenharmony_ci LOS_ListDelete(&resumedTask->pendList); 2810d163575Sopenharmony_ci resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; 2820d163575Sopenharmony_ci 2830d163575Sopenharmony_ci if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { 2840d163575Sopenharmony_ci OsSchedTimeoutQueueDelete(resumedTask); 2850d163575Sopenharmony_ci resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; 2860d163575Sopenharmony_ci } 2870d163575Sopenharmony_ci 2880d163575Sopenharmony_ci if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { 2890d163575Sopenharmony_ci#ifdef LOSCFG_SCHED_EDF_DEBUG 2900d163575Sopenharmony_ci resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; 2910d163575Sopenharmony_ci resumedTask->schedStat.pendCount++; 2920d163575Sopenharmony_ci#endif 2930d163575Sopenharmony_ci EDFEnqueue(OsSchedRunqueue(), resumedTask); 2940d163575Sopenharmony_ci } 2950d163575Sopenharmony_ci} 2960d163575Sopenharmony_ci 2970d163575Sopenharmony_ciSTATIC BOOL EDFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param) 2980d163575Sopenharmony_ci{ 2990d163575Sopenharmony_ci SchedRunqueue *rq = OsSchedRunqueue(); 3000d163575Sopenharmony_ci SchedEDF *sched = (SchedEDF *)&taskCB->sp; 3010d163575Sopenharmony_ci 3020d163575Sopenharmony_ci taskCB->timeSlice = 0; 3030d163575Sopenharmony_ci sched->runTime = (INT32)OS_SYS_US_TO_CYCLE(param->runTimeUs); 3040d163575Sopenharmony_ci sched->period = OS_SYS_US_TO_CYCLE(param->periodUs); 3050d163575Sopenharmony_ci 3060d163575Sopenharmony_ci if (taskCB->taskStatus & OS_TASK_STATUS_READY) { 3070d163575Sopenharmony_ci EDFDequeue(rq, taskCB); 3080d163575Sopenharmony_ci sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs); 3090d163575Sopenharmony_ci EDFEnqueue(rq, taskCB); 3100d163575Sopenharmony_ci return TRUE; 3110d163575Sopenharmony_ci } 3120d163575Sopenharmony_ci 3130d163575Sopenharmony_ci sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs); 3140d163575Sopenharmony_ci if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { 3150d163575Sopenharmony_ci EDFEnqueue(rq, taskCB); 3160d163575Sopenharmony_ci return TRUE; 3170d163575Sopenharmony_ci } 3180d163575Sopenharmony_ci 3190d163575Sopenharmony_ci if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { 3200d163575Sopenharmony_ci return TRUE; 3210d163575Sopenharmony_ci } 3220d163575Sopenharmony_ci 3230d163575Sopenharmony_ci return FALSE; 3240d163575Sopenharmony_ci} 3250d163575Sopenharmony_ci 3260d163575Sopenharmony_ciSTATIC UINT32 EDFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param) 3270d163575Sopenharmony_ci{ 3280d163575Sopenharmony_ci SchedEDF *sched = (SchedEDF *)&taskCB->sp; 3290d163575Sopenharmony_ci param->policy = sched->policy; 3300d163575Sopenharmony_ci param->runTimeUs = (INT32)OS_SYS_CYCLE_TO_US((UINT64)sched->runTime); 3310d163575Sopenharmony_ci param->deadlineUs = OS_SYS_CYCLE_TO_US(sched->deadline); 3320d163575Sopenharmony_ci param->periodUs = OS_SYS_CYCLE_TO_US(sched->period); 3330d163575Sopenharmony_ci return LOS_OK; 3340d163575Sopenharmony_ci} 3350d163575Sopenharmony_ci 3360d163575Sopenharmony_ciSTATIC UINT32 EDFSuspend(LosTaskCB *taskCB) 3370d163575Sopenharmony_ci{ 3380d163575Sopenharmony_ci return LOS_EOPNOTSUPP; 3390d163575Sopenharmony_ci} 3400d163575Sopenharmony_ci 3410d163575Sopenharmony_ciSTATIC UINT32 EDFResume(LosTaskCB *taskCB, BOOL *needSched) 3420d163575Sopenharmony_ci{ 3430d163575Sopenharmony_ci return LOS_EOPNOTSUPP; 3440d163575Sopenharmony_ci} 3450d163575Sopenharmony_ci 3460d163575Sopenharmony_ciSTATIC INT32 EDFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2) 3470d163575Sopenharmony_ci{ 3480d163575Sopenharmony_ci const SchedEDF *param1 = (const SchedEDF *)sp1; 3490d163575Sopenharmony_ci const SchedEDF *param2 = (const SchedEDF *)sp2; 3500d163575Sopenharmony_ci 3510d163575Sopenharmony_ci return (INT32)(param1->finishTime - param2->finishTime); 3520d163575Sopenharmony_ci} 3530d163575Sopenharmony_ci 3540d163575Sopenharmony_ciSTATIC VOID EDFPriorityInheritance(LosTaskCB *owner, const SchedParam *param) 3550d163575Sopenharmony_ci{ 3560d163575Sopenharmony_ci (VOID)owner; 3570d163575Sopenharmony_ci (VOID)param; 3580d163575Sopenharmony_ci} 3590d163575Sopenharmony_ci 3600d163575Sopenharmony_ciSTATIC VOID EDFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param) 3610d163575Sopenharmony_ci{ 3620d163575Sopenharmony_ci (VOID)owner; 3630d163575Sopenharmony_ci (VOID)list; 3640d163575Sopenharmony_ci (VOID)param; 3650d163575Sopenharmony_ci} 3660d163575Sopenharmony_ci 3670d163575Sopenharmony_ciUINT32 EDFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy, 3680d163575Sopenharmony_ci const SchedParam *parentParam, 3690d163575Sopenharmony_ci const LosSchedParam *param) 3700d163575Sopenharmony_ci{ 3710d163575Sopenharmony_ci (VOID)parentParam; 3720d163575Sopenharmony_ci SchedEDF *sched = (SchedEDF *)&taskCB->sp; 3730d163575Sopenharmony_ci sched->flags = EDF_INIT; 3740d163575Sopenharmony_ci sched->policy = policy; 3750d163575Sopenharmony_ci sched->runTime = (INT32)OS_SYS_US_TO_CYCLE((UINT64)param->runTimeUs); 3760d163575Sopenharmony_ci sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs); 3770d163575Sopenharmony_ci sched->period = OS_SYS_US_TO_CYCLE(param->periodUs); 3780d163575Sopenharmony_ci sched->finishTime = 0; 3790d163575Sopenharmony_ci taskCB->timeSlice = 0; 3800d163575Sopenharmony_ci taskCB->ops = &g_deadlineOps; 3810d163575Sopenharmony_ci return LOS_OK; 3820d163575Sopenharmony_ci} 3830d163575Sopenharmony_ci 3840d163575Sopenharmony_ciVOID EDFProcessDefaultSchedParamGet(SchedParam *param) 3850d163575Sopenharmony_ci{ 3860d163575Sopenharmony_ci param->runTimeUs = OS_SCHED_EDF_MIN_RUNTIME; 3870d163575Sopenharmony_ci param->deadlineUs = OS_SCHED_EDF_MAX_DEADLINE; 3880d163575Sopenharmony_ci param->periodUs = param->deadlineUs; 3890d163575Sopenharmony_ci} 3900d163575Sopenharmony_ci 3910d163575Sopenharmony_ciVOID EDFSchedPolicyInit(SchedRunqueue *rq) 3920d163575Sopenharmony_ci{ 3930d163575Sopenharmony_ci if (ArchCurrCpuid() > 0) { 3940d163575Sopenharmony_ci rq->edfRunqueue = &g_schedEDF; 3950d163575Sopenharmony_ci return; 3960d163575Sopenharmony_ci } 3970d163575Sopenharmony_ci 3980d163575Sopenharmony_ci EDFRunqueue *erq = &g_schedEDF; 3990d163575Sopenharmony_ci erq->period = OS_SCHED_MAX_RESPONSE_TIME; 4000d163575Sopenharmony_ci LOS_ListInit(&erq->root); 4010d163575Sopenharmony_ci LOS_ListInit(&erq->waitList); 4020d163575Sopenharmony_ci rq->edfRunqueue = erq; 4030d163575Sopenharmony_ci} 404