From eddcb840d3c5ff0d79c3175349bdee1719f52b95 Mon Sep 17 00:00:00 2001 From: zhushengle Date: Tue, 29 Mar 2022 14:38:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=B0=83=E5=BA=A6?= =?UTF-8?q?=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close #I4Z3BL Signed-off-by: zhushengle Change-Id: I5f32d1001ffabc0f725ce65b51ed9b3791e97f2b --- arch/arm/arm/src/los_hwi.c | 2 +- compat/posix/src/pthread.c | 4 +- kernel/base/BUILD.gn | 4 +- kernel/base/core/los_process.c | 105 ++- kernel/base/core/los_swtmr.c | 48 +- kernel/base/core/los_task.c | 103 +-- kernel/base/include/los_mux_pri.h | 4 +- kernel/base/include/los_process_pri.h | 9 +- kernel/base/include/los_rwlock_pri.h | 4 +- kernel/base/include/los_sched_pri.h | 274 +++++-- kernel/base/include/los_task_pri.h | 22 +- kernel/base/ipc/los_event.c | 6 +- kernel/base/ipc/los_futex.c | 57 +- kernel/base/ipc/los_mux.c | 103 +-- kernel/base/ipc/los_queue.c | 13 +- kernel/base/ipc/los_rwlock.c | 32 +- kernel/base/ipc/los_sem.c | 10 +- kernel/base/ipc/los_signal.c | 12 +- kernel/base/misc/task_shellcmd.c | 304 ++++---- kernel/base/mp/los_mp.c | 2 +- kernel/base/sched/los_idle.c | 187 +++++ kernel/base/sched/los_priority.c | 546 ++++++++++++++ kernel/base/sched/los_sched.c | 675 ++++-------------- kernel/base/sched/los_sortlink.c | 3 +- kernel/base/sched/los_statistics.c | 6 +- kernel/common/los_config.c | 2 +- kernel/common/los_config.h | 11 +- kernel/extended/liteipc/hm_liteipc.c | 6 +- kernel/extended/power/los_pm.c | 4 +- kernel/extended/trace/cnv/trace_cnv.c | 40 +- kernel/extended/trace/los_trace.c | 6 +- syscall/process_syscall.c | 35 +- .../core/task/smp/It_smp_los_task_101.c | 2 +- .../core/task/smp/It_smp_los_task_127.c | 2 +- .../basic/process/smoke/process_test_044.cpp | 6 +- 35 files changed, 1570 insertions(+), 1079 deletions(-) create mode 100644 kernel/base/sched/los_idle.c create mode 100644 kernel/base/sched/los_priority.c diff --git a/arch/arm/arm/src/los_hwi.c b/arch/arm/arm/src/los_hwi.c index 24271524..dd41e50d 100644 --- a/arch/arm/arm/src/los_hwi.c +++ b/arch/arm/arm/src/los_hwi.c @@ -104,7 +104,7 @@ VOID OsInterrupt(UINT32 intNum) ++g_hwiFormCnt[cpuid][intNum]; OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, intNum); - OsSchedIrqUpdateUsedTime(); + OsSchedIrqUsedTimeUpdate(); #ifdef LOSCFG_CPUP_INCLUDE_IRQ OsCpupIrqEnd(cpuid, intNum); diff --git a/compat/posix/src/pthread.c b/compat/posix/src/pthread.c index 1fd5c4ff..2857a6e1 100644 --- a/compat/posix/src/pthread.c +++ b/compat/posix/src/pthread.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -158,7 +158,7 @@ STATIC VOID SetPthreadAttr(const _pthread_data *self, const pthread_attr_t *attr } if (outAttr->inheritsched == PTHREAD_INHERIT_SCHED) { if (self->task == NULL) { - outAttr->schedparam.sched_priority = ((LosTaskCB *)(OsCurrTaskGet()))->priority; + outAttr->schedparam.sched_priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID); } else { outAttr->schedpolicy = self->attr.schedpolicy; outAttr->schedparam = self->attr.schedparam; diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn index 003b615d..936816d0 100644 --- a/kernel/base/BUILD.gn +++ b/kernel/base/BUILD.gn @@ -1,5 +1,5 @@ # Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. -# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: @@ -66,6 +66,8 @@ kernel_module(module_name) { "mp/los_percpu.c", "mp/los_spinlock.c", "om/los_err.c", + "sched/los_idle.c", + "sched/los_priority.c", "sched/los_sched.c", "sched/los_sortlink.c", "sched/los_statistics.c", diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 025ee129..135bdf3f 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -87,7 +87,7 @@ VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) OsTaskInsertToRecycleList(taskCB); } -UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB) +UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB, SchedParam *param) { UINT32 intSave; UINT16 numCount; @@ -100,12 +100,14 @@ UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB) if (OsProcessIsUserMode(processCB)) { taskCB->taskStatus |= OS_TASK_FLAG_USER_MODE; if (processCB->threadNumber > 0) { - taskCB->basePrio = OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio; + LosTaskCB *task = OS_TCB_FROM_TID(processCB->threadGroupID); + task->ops->schedParamGet(task, param); } else { - taskCB->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST; + OsSchedProcessDefaultSchedParamGet(param->policy, param); } } else { - taskCB->basePrio = OsCurrTaskGet()->basePrio; + LosTaskCB *runTask = OsCurrTaskGet(); + runTask->ops->schedParamGet(runTask, param); } #ifdef LOSCFG_KERNEL_VM @@ -283,7 +285,7 @@ STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, INT32 VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID) { taskCB->waitID = wakePID; - OsSchedTaskWake(taskCB); + taskCB->ops->wake(taskCB); #ifdef LOSCFG_KERNEL_SMP LOS_MpSchedule(OS_MP_CPU_ALL); #endif @@ -897,7 +899,7 @@ STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 p } #ifdef LOSCFG_SECURITY_CAPABILITY -STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio) +STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 prio) { LosProcessCB *runProcess = OsCurrProcessGet(); @@ -907,7 +909,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio) } /* user mode process can reduce the priority of itself */ - if ((runProcess->processID == processCB->processID) && (prio > OsCurrTaskGet()->basePrio)) { + if ((runProcess->processID == processCB->processID) && (prio > param->basePrio)) { return TRUE; } @@ -921,31 +923,33 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio) LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy) { - LosProcessCB *processCB = NULL; - BOOL needSched = FALSE; + SchedParam param = { 0 }; UINT32 intSave; - INT32 ret; - ret = OsProcessSchedlerParamCheck(which, pid, prio, policy); + INT32 ret = OsProcessSchedlerParamCheck(which, pid, prio, policy); if (ret != LOS_OK) { return -ret; } + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); SCHEDULER_LOCK(intSave); - processCB = OS_PCB_FROM_PID(pid); if (OsProcessIsInactive(processCB)) { ret = LOS_ESRCH; goto EXIT; } #ifdef LOSCFG_SECURITY_CAPABILITY - if (!OsProcessCapPermitCheck(processCB, prio)) { + if (!OsProcessCapPermitCheck(processCB, ¶m, prio)) { ret = LOS_EPERM; goto EXIT; } #endif - needSched = OsSchedModifyProcessSchedParam(pid, policy, prio); + LosTaskCB *taskCB = OS_TCB_FROM_TID(processCB->threadGroupID); + taskCB->ops->schedParamGet(taskCB, ¶m); + param.basePrio = prio; + + BOOL needSched = taskCB->ops->schedParamModify(taskCB, ¶m); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); @@ -993,6 +997,7 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) { INT32 prio; UINT32 intSave; + SchedParam param = { 0 }; (VOID)which; if (OS_PID_CHECK_INVALID(pid)) { @@ -1010,11 +1015,12 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) goto OUT; } - prio = (INT32)OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio; + LosTaskCB *taskCB = OS_TCB_FROM_TID(processCB->threadGroupID); + taskCB->ops->schedParamGet(taskCB, ¶m); OUT: SCHEDULER_UNLOCK(intSave); - return prio; + return param.basePrio; } LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid) @@ -1050,8 +1056,7 @@ STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *proces /* if runTask->waitFlag == OS_PROCESS_WAIT_PRO, * this node is inserted directly into the header of the waitList */ - - (VOID)OsSchedTaskWait(list->pstNext, LOS_WAIT_FOREVER, TRUE); + (VOID)runTask->ops->wait(runTask, list->pstNext, LOS_WAIT_FOREVER); return; } @@ -1202,13 +1207,10 @@ STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 UINT32 ret; UINT32 intSave; LosProcessCB *childCB = NULL; - LosProcessCB *processCB = NULL; - LosTaskCB *runTask = NULL; + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - processCB = OsCurrProcessGet(); - runTask = OsCurrTaskGet(); - ret = OsWaitChildProcessCheck(processCB, pid, &childCB); if (ret != LOS_OK) { pid = -ret; @@ -1725,47 +1727,37 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) return LOS_OK; } -STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size, - TSK_INIT_PARAM_S *childPara) +STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size) { - LosTaskCB *mainThread = NULL; - UINT32 intSave; + LosTaskCB *runTask = OsCurrTaskGet(); + TSK_INIT_PARAM_S taskParam = { 0 }; + UINT32 ret, taskID, intSave; + SchedParam param = { 0 }; SCHEDULER_LOCK(intSave); - mainThread = OsCurrTaskGet(); - if (OsProcessIsUserMode(childProcessCB)) { - childPara->pfnTaskEntry = mainThread->taskEntry; - childPara->uwStackSize = mainThread->stackSize; - childPara->userParam.userArea = mainThread->userArea; - childPara->userParam.userMapBase = mainThread->userMapBase; - childPara->userParam.userMapSize = mainThread->userMapSize; + taskParam.pfnTaskEntry = runTask->taskEntry; + taskParam.uwStackSize = runTask->stackSize; + taskParam.userParam.userArea = runTask->userArea; + taskParam.userParam.userMapBase = runTask->userMapBase; + taskParam.userParam.userMapSize = runTask->userMapSize; } else { - childPara->pfnTaskEntry = (TSK_ENTRY_FUNC)entry; - childPara->uwStackSize = size; + taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)entry; + taskParam.uwStackSize = size; } - childPara->pcName = (CHAR *)name; - childPara->policy = mainThread->policy; - childPara->usTaskPrio = mainThread->priority; - childPara->processID = childProcessCB->processID; - if (mainThread->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { - childPara->uwResved = LOS_TASK_ATTR_JOINABLE; + if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + taskParam.uwResved = LOS_TASK_ATTR_JOINABLE; } + runTask->ops->schedParamGet(runTask, ¶m); SCHEDULER_UNLOCK(intSave); -} - -STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size) -{ - LosTaskCB *runTask = OsCurrTaskGet(); - TSK_INIT_PARAM_S childPara = { 0 }; - UINT32 ret; - UINT32 intSave; - UINT32 taskID; - OsInitCopyTaskParam(childProcessCB, name, entry, size, &childPara); + taskParam.pcName = (CHAR *)name; + taskParam.policy = param.policy; + taskParam.usTaskPrio = param.priority; + taskParam.processID = childProcessCB->processID; - ret = LOS_TaskCreateOnly(&taskID, &childPara); + ret = LOS_TaskCreateOnly(&taskID, &taskParam); if (ret != LOS_OK) { if (ret == LOS_ERRNO_TSK_TCB_UNAVAILABLE) { return LOS_EAGAIN; @@ -1775,7 +1767,7 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID); childTaskCB->taskStatus = runTask->taskStatus; - childTaskCB->basePrio = runTask->basePrio; + childTaskCB->ops->schedParamModify(childTaskCB, ¶m); if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) { childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING; } else { @@ -1882,6 +1874,7 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB * UINT32 ret; ProcessGroup *group = NULL; + LosTaskCB *taskCB = OS_TCB_FROM_TID(child->threadGroupID); SCHEDULER_LOCK(intSave); if (run->group->groupID == OS_USER_PRIVILEGE_PROCESS_GROUP) { ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &group); @@ -1892,7 +1885,7 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB * } child->processStatus &= ~OS_PROCESS_STATUS_INIT; - OsSchedTaskEnQueue(OS_TCB_FROM_TID(child->threadGroupID)); + taskCB->ops->enqueue(OsSchedRunqueue(), taskCB); SCHEDULER_UNLOCK(intSave); (VOID)LOS_MemFree(m_aucSysMem1, group); diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index c8b53935..9ef4a547 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -59,9 +59,9 @@ typedef struct { SortLinkAttribute swtmrSortLink; LosTaskCB *swtmrTask; /* software timer task id */ LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */ -} SwtmrRunQue; +} SwtmrRunqueue; -STATIC SwtmrRunQue g_swtmrRunQue[LOSCFG_KERNEL_CORE_NUM]; +STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM]; #ifdef LOSCFG_SWTMR_DEBUG #define OS_SWTMR_PERIOD_TO_CYCLE(period) (((UINT64)(period) * OS_NS_PER_TICK) / OS_NS_PER_CYCLE) @@ -182,7 +182,7 @@ STATIC INLINE VOID SwtmrHandler(SwtmrHandlerItemPtr swtmrHandle) #endif } -STATIC INLINE VOID SwtmrWake(SwtmrRunQue *srq, UINT64 startTime, SortLinkList *sortList) +STATIC INLINE VOID SwtmrWake(SwtmrRunqueue *srq, UINT64 startTime, SortLinkList *sortList) { UINT32 intSave; SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); @@ -216,7 +216,7 @@ STATIC INLINE VOID SwtmrWake(SwtmrRunQue *srq, UINT64 startTime, SortLinkList *s SWTMR_UNLOCK(intSave); } -STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunQue *srq) +STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq) { UINT32 intSave; SortLinkAttribute *swtmrSortLink = &srq->swtmrSortLink; @@ -261,13 +261,13 @@ STATIC VOID SwtmrTask(VOID) UINT32 intSave; UINT64 waitTime; - SwtmrRunQue *srq = &g_swtmrRunQue[ArchCurrCpuid()]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()]; LOS_DL_LIST *head = &srq->swtmrHandlerQueue; for (;;) { waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink); if (waitTime != 0) { SCHEDULER_LOCK(intSave); - OsSchedDelay(srq->swtmrTask, waitTime); + srq->swtmrTask->ops->delay(srq->swtmrTask, waitTime); OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, srq->swtmrTask); SCHEDULER_UNLOCK(intSave); } @@ -309,7 +309,7 @@ STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID) UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid) { - return g_swtmrRunQue[cpuid].swtmrTask->taskID; + return g_swtmrRunqueue[cpuid].swtmrTask->taskID; } BOOL OsIsSwtmrTask(const LosTaskCB *taskCB) @@ -358,7 +358,7 @@ STATIC UINT32 SwtmrBaseInit(VOID) } for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { - SwtmrRunQue *srq = &g_swtmrRunQue[index]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[index]; /* The linked list of all cores must be initialized at core 0 startup for load balancing */ OsSortLinkInit(&srq->swtmrSortLink); LOS_ListInit(&srq->swtmrHandlerQueue); @@ -389,7 +389,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) goto ERROR; } - SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; srq->swtmrTask = OsGetTaskCB(swtmrTaskID); return LOS_OK; @@ -403,13 +403,13 @@ ERROR: } #ifdef LOSCFG_KERNEL_SMP -STATIC INLINE VOID FindIdleSwtmrRunQue(UINT16 *idleCpuid) +STATIC INLINE VOID FindIdleSwtmrRunqueue(UINT16 *idleCpuid) { - SwtmrRunQue *idleRq = &g_swtmrRunQue[0]; + SwtmrRunqueue *idleRq = &g_swtmrRunqueue[0]; UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->swtmrSortLink); UINT16 cpuid = 1; do { - SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; UINT32 temp = OsGetSortLinkNodeNum(&srq->swtmrSortLink); if (nodeNum > temp) { *idleCpuid = cpuid; @@ -422,7 +422,7 @@ STATIC INLINE VOID FindIdleSwtmrRunQue(UINT16 *idleCpuid) STATIC INLINE VOID AddSwtmr2TimeList(SortLinkList *node, UINT64 responseTime, UINT16 cpuid) { - SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; OsAdd2SortLink(&srq->swtmrSortLink, node, responseTime, cpuid); } @@ -433,7 +433,7 @@ STATIC INLINE VOID DeSwtmrFromTimeList(SortLinkList *node) #else UINT16 cpuid = 0; #endif - SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; OsDeleteFromSortLink(&srq->swtmrSortLink, node); return; } @@ -442,7 +442,7 @@ STATIC VOID SwtmrAdjustCheck(UINT16 cpuid, UINT64 responseTime) { UINT32 ret; UINT32 intSave; - SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid]; SCHEDULER_LOCK(intSave); if ((srq->swtmrTask == NULL) || !OsTaskIsBlocked(srq->swtmrTask)) { SCHEDULER_UNLOCK(intSave); @@ -454,14 +454,14 @@ STATIC VOID SwtmrAdjustCheck(UINT16 cpuid, UINT64 responseTime) return; } - ret = OsSchedAdjustTaskFromTimeList(srq->swtmrTask, responseTime); + ret = OsSchedTimeoutQueueAdjust(srq->swtmrTask, responseTime); SCHEDULER_UNLOCK(intSave); if (ret != LOS_OK) { return; } if (cpuid == ArchCurrCpuid()) { - OsSchedUpdateExpireTime(); + OsSchedExpireTimeUpdate(); } else { LOS_MpSchedule(CPUID_TO_AFFI_MASK(cpuid)); } @@ -505,7 +505,7 @@ STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr) UINT64 responseTime; UINT16 idleCpu = 0; #ifdef LOSCFG_KERNEL_SMP - FindIdleSwtmrRunQue(&idleCpu); + FindIdleSwtmrRunqueue(&idleCpu); #endif swtmr->startTime = OsGetCurrSchedTimeCycle(); responseTime = SwtmrToStart(swtmr, idleCpu); @@ -543,7 +543,7 @@ STATIC INLINE VOID SwtmrRestart(UINT64 startTime, SortLinkList *sortList, UINT16 VOID OsSwtmrResponseTimeReset(UINT64 startTime) { UINT16 cpuid = ArchCurrCpuid(); - SortLinkAttribute *swtmrSortLink = &g_swtmrRunQue[cpuid].swtmrSortLink; + SortLinkAttribute *swtmrSortLink = &g_swtmrRunqueue[cpuid].swtmrSortLink; LOS_DL_LIST *listHead = &swtmrSortLink->sortLink; LOS_DL_LIST *listNext = listHead->pstNext; @@ -561,7 +561,7 @@ VOID OsSwtmrResponseTimeReset(UINT64 startTime) LOS_SpinUnlock(&swtmrSortLink->spinLock); } -STATIC INLINE BOOL SwtmrRunQueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +STATIC INLINE BOOL SwtmrRunqueueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) { LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; LOS_DL_LIST *list = listObject->pstNext; @@ -583,8 +583,8 @@ STATIC INLINE BOOL SwtmrRunQueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FI STATIC BOOL SwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) { for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { - SortLinkAttribute *swtmrSortLink = &g_swtmrRunQue[ArchCurrCpuid()].swtmrSortLink; - if (SwtmrRunQueFind(swtmrSortLink, checkFunc, arg)) { + SortLinkAttribute *swtmrSortLink = &g_swtmrRunqueue[ArchCurrCpuid()].swtmrSortLink; + if (SwtmrRunqueueFind(swtmrSortLink, checkFunc, arg)) { return TRUE; } } @@ -608,7 +608,7 @@ BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) { UINT64 currTime = OsGetCurrSchedTimeCycle(); - SwtmrRunQue *srq = &g_swtmrRunQue[ArchCurrCpuid()]; + SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()]; UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &srq->swtmrSortLink) / OS_CYCLE_PER_TICK); if (time > OS_INVALID_VALUE) { time = OS_INVALID_VALUE; diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 14ee0598..bcddc312 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -90,19 +90,23 @@ VOID OsSetMainTask() { UINT32 i; CHAR *name = "osMain"; + SchedParam schedParam = { 0 }; + + schedParam.policy = LOS_SCHED_RR; + schedParam.basePrio = OS_PROCESS_PRIORITY_HIGHEST; + schedParam.priority = OS_TASK_PRIORITY_LOWEST; for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED; g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT; g_mainTask[i].processID = OS_KERNEL_PROCESS_GROUP; - g_mainTask[i].basePrio = OS_TASK_PRIORITY_HIGHEST; - g_mainTask[i].priority = OS_TASK_PRIORITY_LOWEST; #ifdef LOSCFG_KERNEL_SMP_LOCKDEP g_mainTask[i].lockDep.lockDepth = 0; g_mainTask[i].lockDep.waitLock = NULL; #endif (VOID)strncpy_s(g_mainTask[i].taskName, OS_TCB_NAME_LEN, name, OS_TCB_NAME_LEN - 1); LOS_ListInit(&g_mainTask[i].lockList); + (VOID)OsSchedParamInit(&g_mainTask[i], schedParam.policy, &schedParam, NULL); } } @@ -124,7 +128,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB) if (!LOS_ListEmpty(&taskCB->joinList)) { LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList))); OsTaskWakeClearPendMask(resumedTask); - OsSchedTaskWake(resumedTask); + resumedTask->ops->wake(resumedTask); } } taskCB->taskStatus |= OS_TASK_STATUS_EXIT; @@ -142,7 +146,8 @@ LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) if ((taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) && LOS_ListEmpty(&taskCB->joinList)) { OsTaskWaitSetPendMask(OS_TASK_WAIT_JOIN, taskCB->taskID, LOS_WAIT_FOREVER); - return OsSchedTaskWait(&taskCB->joinList, LOS_WAIT_FOREVER, TRUE); + LosTaskCB *runTask = OsCurrTaskGet(); + return runTask->ops->wait(runTask, &taskCB->joinList, LOS_WAIT_FOREVER); } return LOS_EINVAL; @@ -201,7 +206,7 @@ EXIT: UINT32 OsGetIdleTaskId(VOID) { - return OsSchedGetRunQueIdle(); + return OsSchedRunqueueIdleGet(); } LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) @@ -214,6 +219,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask; taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; taskInitParam.pcName = "Idle"; + taskInitParam.policy = LOS_SCHED_IDLE; taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST; taskInitParam.processID = OsGetIdleProcessID(); #ifdef LOSCFG_KERNEL_SMP @@ -222,10 +228,9 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam); LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID); idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; - OsSchedRunQueIdleInit(idleTaskID); - OsSchedSetIdleTaskSchedParam(idleTask); + OsSchedRunqueueIdleInit(idleTaskID); - return ret; + return LOS_TaskResume(idleTaskID); } /* @@ -458,10 +463,8 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskStackAlloc(VOID **topStack, UINT32 stack *topStack = (VOID *)LOS_MemAllocAlign(pool, stackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); } -LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, - const VOID *stackPtr, - const VOID *topStack, - const TSK_INIT_PARAM_S *initParam) +STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const VOID *stackPtr, const VOID *topStack, + const TSK_INIT_PARAM_S *initParam) { taskCB->stackPointer = (VOID *)stackPtr; taskCB->args[0] = initParam->auwArgs[0]; /* 0~3: just for args array index */ @@ -470,7 +473,6 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, taskCB->args[3] = initParam->auwArgs[3]; taskCB->topOfStack = (UINTPTR)topStack; taskCB->stackSize = initParam->uwStackSize; - taskCB->priority = initParam->usTaskPrio; taskCB->taskEntry = initParam->pfnTaskEntry; taskCB->signal = SIGNAL_NONE; @@ -479,7 +481,6 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, taskCB->cpuAffiMask = (initParam->usCpuAffiMask) ? initParam->usCpuAffiMask : LOSCFG_KERNEL_CPU_MASK; #endif - taskCB->policy = (initParam->policy == LOS_SCHED_FIFO) ? LOS_SCHED_FIFO : LOS_SCHED_RR; taskCB->taskStatus = OS_TASK_STATUS_INIT; if (initParam->uwResved & LOS_TASK_ATTR_JOINABLE) { taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; @@ -495,10 +496,13 @@ STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, { UINT32 ret; UINT32 numCount; + SchedParam schedParam = { 0 }; + UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy; - OsTaskCBInitBase(taskCB, stackPtr, topStack, initParam); + TaskCBBaseInit(taskCB, stackPtr, topStack, initParam); - numCount = OsProcessAddNewTask(initParam->processID, taskCB); + schedParam.policy = policy; + numCount = OsProcessAddNewTask(initParam->processID, taskCB, &schedParam); #ifdef LOSCFG_KERNEL_VM taskCB->futex.index = OS_INVALID_VALUE; if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) { @@ -509,6 +513,11 @@ STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, } #endif + ret = OsSchedParamInit(taskCB, policy, &schedParam, initParam); + if (ret != LOS_OK) { + return ret; + } + if (initParam->pcName != NULL) { ret = (UINT32)OsSetTaskName(taskCB, initParam->pcName, FALSE); if (ret == LOS_OK) { @@ -622,7 +631,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in LosTaskCB *taskCB = OS_TCB_FROM_TID(*taskID); SCHEDULER_LOCK(intSave); - OsSchedTaskEnQueue(taskCB); + taskCB->ops->enqueue(OsSchedRunqueue(), taskCB); SCHEDULER_UNLOCK(intSave); /* in case created task not running on this core, @@ -639,13 +648,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) { UINT32 intSave; UINT32 errRet; - LosTaskCB *taskCB = NULL; + BOOL needSched = FALSE; if (OS_TID_CHECK_INVALID(taskID)) { return LOS_ERRNO_TSK_ID_INVALID; } - taskCB = OS_TCB_FROM_TID(taskID); + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); SCHEDULER_LOCK(intSave); /* clear pending signal */ @@ -659,7 +668,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) OS_GOTO_ERREND(); } - BOOL needSched = OsSchedResume(taskCB); + errRet = taskCB->ops->resume(taskCB, &needSched); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); @@ -667,7 +676,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) LOS_Schedule(); } - return LOS_OK; + return errRet; LOS_ERREND: SCHEDULER_UNLOCK(intSave); @@ -715,9 +724,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB) { UINT32 errRet; - UINT16 tempStatus; - - tempStatus = taskCB->taskStatus; + UINT16 tempStatus = taskCB->taskStatus; if (tempStatus & OS_TASK_STATUS_UNUSED) { return LOS_ERRNO_TSK_NOT_CREATED; } @@ -731,8 +738,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB) return errRet; } - OsSchedSuspend(taskCB); - return LOS_OK; + return taskCB->ops->suspend(taskCB); } LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID) @@ -833,11 +839,11 @@ LITE_OS_SEC_TEXT VOID OsInactiveTaskDelete(LosTaskCB *taskCB) OsTaskReleaseHoldLock(taskCB); - OsSchedTaskExit(taskCB); + taskCB->ops->exit(taskCB); if (taskStatus & OS_TASK_STATUS_PENDING) { LosMux *mux = (LosMux *)taskCB->taskMux; if (LOS_MuxIsValid(mux) == TRUE) { - OsMuxBitmapRestore(mux, taskCB, (LosTaskCB *)mux->owner); + OsMuxBitmapRestore(mux, NULL, taskCB); } } @@ -925,17 +931,16 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) } SCHEDULER_LOCK(intSave); - OsSchedDelay(runTask, OS_SCHED_TICK_TO_CYCLE(tick)); + UINT32 ret = runTask->ops->delay(runTask, OS_SCHED_TICK_TO_CYCLE(tick)); OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, runTask); SCHEDULER_UNLOCK(intSave); - - return LOS_OK; + return ret; } LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) { UINT32 intSave; - UINT16 priority; + SchedParam param = { 0 }; if (OS_TID_CHECK_INVALID(taskID)) { return (UINT16)OS_INVALID; @@ -948,14 +953,15 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) return (UINT16)OS_INVALID; } - priority = taskCB->priority; + taskCB->ops->schedParamGet(taskCB, ¶m); SCHEDULER_UNLOCK(intSave); - return priority; + return param.priority; } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) { UINT32 intSave; + SchedParam param = { 0 }; if (taskPrio > OS_TASK_PRIORITY_LOWEST) { return LOS_ERRNO_TSK_PRIOR_ERROR; @@ -976,11 +982,15 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) return LOS_ERRNO_TSK_NOT_CREATED; } - BOOL isReady = OsSchedModifyTaskSchedParam(taskCB, taskCB->policy, taskPrio); + taskCB->ops->schedParamGet(taskCB, ¶m); + + param.priority = taskPrio; + + BOOL needSched = taskCB->ops->schedParamModify(taskCB, ¶m); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); - if (isReady && OS_SCHEDULER_ACTIVE) { + if (needSched && OS_SCHEDULER_ACTIVE) { LOS_Schedule(); } return LOS_OK; @@ -1010,7 +1020,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID) SCHEDULER_LOCK(intSave); /* reset timeslice of yielded task */ - OsSchedYield(); + runTask->ops->yield(runTask); SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -1040,6 +1050,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo) { UINT32 intSave; + SchedParam param = { 0 }; if (taskInfo == NULL) { return LOS_ERRNO_TSK_PTR_NULL; @@ -1062,8 +1073,9 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf taskInfo->uwSP = ArchSPGet(); } + taskCB->ops->schedParamGet(taskCB, ¶m); taskInfo->usTaskStatus = taskCB->taskStatus; - taskInfo->usTaskPrio = taskCB->priority; + taskInfo->usTaskPrio = param.priority; taskInfo->uwStackSize = taskCB->stackSize; taskInfo->uwTopOfStack = taskCB->topOfStack; taskInfo->uwEventMask = taskCB->eventMask; @@ -1200,7 +1212,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID) } else if (runTask->signal & SIGNAL_AFFI) { runTask->signal &= ~SIGNAL_AFFI; - /* pri-queue has updated, notify the target cpu */ + /* priority queue has updated, notify the target cpu */ LOS_MpSchedule((UINT32)runTask->cpuAffiMask); #endif } @@ -1340,6 +1352,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID) { UINT32 intSave; INT32 policy; + SchedParam param = { 0 }; if (OS_TID_CHECK_INVALID(taskID)) { return -LOS_EINVAL; @@ -1352,7 +1365,8 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID) OS_GOTO_ERREND(); } - policy = taskCB->policy; + taskCB->ops->schedParamGet(taskCB, ¶m); + policy = (INT32)param.policy; LOS_ERREND: SCHEDULER_UNLOCK(intSave); @@ -1361,8 +1375,8 @@ LOS_ERREND: LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority) { + SchedParam param = { 0 }; UINT32 intSave; - BOOL needSched = FALSE; if (OS_TID_CHECK_INVALID(taskID)) { return LOS_ESRCH; @@ -1387,7 +1401,10 @@ LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 return LOS_EINVAL; } - needSched = OsSchedModifyTaskSchedParam(taskCB, policy, priority); + taskCB->ops->schedParamGet(taskCB, ¶m); + param.policy = policy; + param.priority = priority; + BOOL needSched = taskCB->ops->schedParamModify(taskCB, ¶m); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); diff --git a/kernel/base/include/los_mux_pri.h b/kernel/base/include/los_mux_pri.h index 129902a8..8837114c 100644 --- a/kernel/base/include/los_mux_pri.h +++ b/kernel/base/include/los_mux_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -43,7 +43,7 @@ extern "C" { #define OS_MUX_MAGIC 0xEBCFDEA0 -extern VOID OsMuxBitmapRestore(const LosMux *mutex, const LosTaskCB *taskCB, LosTaskCB *owner); +extern VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask); extern UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout); extern UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout); extern UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched); diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index dd39accd..45d0dd04 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -295,11 +295,6 @@ STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB) return (processCB->processMode == OS_USER_MODE); } -#define LOS_SCHED_NORMAL 0U -#define LOS_SCHED_FIFO 1U -#define LOS_SCHED_RR 2U -#define LOS_SCHED_IDLE 3U - #define LOS_PRIO_PROCESS 0U #define LOS_PRIO_PGRP 1U #define LOS_PRIO_USER 2U @@ -488,7 +483,7 @@ extern UINTPTR OsGetSigHandler(VOID); extern VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID); extern INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission); extern INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission); -extern UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB); +extern UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB, SchedParam *param); extern VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB); extern VOID OsProcessThreadGroupDestroy(VOID); diff --git a/kernel/base/include/los_rwlock_pri.h b/kernel/base/include/los_rwlock_pri.h index 55681501..c70b42a2 100644 --- a/kernel/base/include/los_rwlock_pri.h +++ b/kernel/base/include/los_rwlock_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -41,7 +41,7 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#define OS_RWLOCK_MAGIC 0xBEFDCAU +#define OS_RWLOCK_MAGIC 0xEFDCAU enum RwlockMode { RWLOCK_NONE_MODE, diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index a894c051..a8dfe1a0 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -41,6 +41,7 @@ #endif #include "los_stackinfo_pri.h" #include "los_futex_pri.h" +#include "los_pm_pri.h" #include "los_signal.h" #ifdef LOSCFG_KERNEL_CPUP #include "los_cpup_pri.h" @@ -66,6 +67,7 @@ extern UINT32 g_taskScheduled; #define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) #define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK) +typedef struct TagTaskCB LosTaskCB; typedef BOOL (*SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR); STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) @@ -79,52 +81,65 @@ typedef enum { INT_PEND_TICK = 0x2, /* pending tick */ } SchedFlag; +#define OS_PRIORITY_QUEUE_NUM 32 typedef struct { - SortLinkAttribute taskSortLink; /* task sort link */ - UINT64 responseTime; /* Response time for current CPU tick interrupts */ - UINT32 responseID; /* The response ID of the current CPU tick interrupt */ - UINT32 idleTaskID; /* idle task id */ - UINT32 taskLockCnt; /* task lock flag */ - UINT32 schedFlag; /* pending scheduler flag */ -} SchedRunQue; + LOS_DL_LIST priQueList[OS_PRIORITY_QUEUE_NUM]; + UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM]; + UINT32 queueBitmap; +} HPFQueue; -extern SchedRunQue g_schedRunQue[LOSCFG_KERNEL_CORE_NUM]; +typedef struct { + HPFQueue queueList[OS_PRIORITY_QUEUE_NUM]; + UINT32 queueBitmap; +} HPFRunqueue; + +typedef struct { + SortLinkAttribute timeoutQueue; /* task timeout queue */ + HPFRunqueue *hpfRunqueue; + UINT64 responseTime; /* Response time for current CPU tick interrupts */ + UINT32 responseID; /* The response ID of the current CPU tick interrupt */ + UINT32 idleTaskID; /* idle task id */ + UINT32 taskLockCnt; /* task lock flag */ + UINT32 schedFlag; /* pending scheduler flag */ +} SchedRunqueue; + +extern SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM]; -VOID OsSchedUpdateExpireTime(VOID); +VOID OsSchedExpireTimeUpdate(VOID); -STATIC INLINE SchedRunQue *OsSchedRunQue(VOID) +STATIC INLINE SchedRunqueue *OsSchedRunqueue(VOID) { - return &g_schedRunQue[ArchCurrCpuid()]; + return &g_schedRunqueue[ArchCurrCpuid()]; } -STATIC INLINE SchedRunQue *OsSchedRunQueByID(UINT16 id) +STATIC INLINE SchedRunqueue *OsSchedRunqueueByID(UINT16 id) { - return &g_schedRunQue[id]; + return &g_schedRunqueue[id]; } STATIC INLINE UINT32 OsSchedLockCountGet(VOID) { - return OsSchedRunQue()->taskLockCnt; + return OsSchedRunqueue()->taskLockCnt; } STATIC INLINE VOID OsSchedLockSet(UINT32 count) { - OsSchedRunQue()->taskLockCnt = count; + OsSchedRunqueue()->taskLockCnt = count; } STATIC INLINE VOID OsSchedLock(VOID) { - OsSchedRunQue()->taskLockCnt++; + OsSchedRunqueue()->taskLockCnt++; } STATIC INLINE VOID OsSchedUnlock(VOID) { - OsSchedRunQue()->taskLockCnt--; + OsSchedRunqueue()->taskLockCnt--; } STATIC INLINE BOOL OsSchedUnlockResch(VOID) { - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); if (rq->taskLockCnt > 0) { rq->taskLockCnt--; if ((rq->taskLockCnt == 0) && (rq->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { @@ -137,13 +152,13 @@ STATIC INLINE BOOL OsSchedUnlockResch(VOID) STATIC INLINE BOOL OsSchedIsLock(VOID) { - return (OsSchedRunQue()->taskLockCnt != 0); + return (OsSchedRunqueue()->taskLockCnt != 0); } /* Check if preemptible with counter flag */ STATIC INLINE BOOL OsPreemptable(VOID) { - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); /* * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable * is called, needs manually disable interrupt, to prevent current task from @@ -162,7 +177,7 @@ STATIC INLINE BOOL OsPreemptable(VOID) STATIC INLINE BOOL OsPreemptableInSched(VOID) { BOOL preemptible = FALSE; - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); #ifdef LOSCFG_KERNEL_SMP /* @@ -182,18 +197,61 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID) return preemptible; } -STATIC INLINE UINT32 OsSchedGetRunQueIdle(VOID) +STATIC INLINE UINT32 OsSchedRunqueueIdleGet(VOID) { - return OsSchedRunQue()->idleTaskID; + return OsSchedRunqueue()->idleTaskID; } -STATIC INLINE VOID OsSchedRunQuePendingSet(VOID) +STATIC INLINE VOID OsSchedRunqueuePendingSet(VOID) { - OsSchedRunQue()->schedFlag |= INT_PEND_RESCH; + OsSchedRunqueue()->schedFlag |= INT_PEND_RESCH; } -VOID OsSchedRunQueIdleInit(UINT32 idleTaskID); -VOID OsSchedRunQueInit(VOID); +#define LOS_SCHED_NORMAL 0U +#define LOS_SCHED_FIFO 1U +#define LOS_SCHED_RR 2U +#define LOS_SCHED_IDLE 3U + +typedef struct { + UINT16 policy; + UINT16 basePrio; + UINT16 priority; + UINT32 timeSlice; +} SchedParam; + +typedef struct { + UINT16 policy; /* This field must be present for all scheduling policies and must be the first in the structure */ + UINT16 basePrio; + UINT16 priority; + UINT32 initTimeSlice; + UINT32 priBitmap; /**< Bitmap for recording the change of task priority, the priority can not be greater than 31 */ +} SchedHPF; + +typedef struct { + union { + SchedHPF hpf; + } Policy; +} SchedPolicy; + +typedef struct { + VOID (*dequeue)(SchedRunqueue *rq, LosTaskCB *taskCB); + VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB); + VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB); + VOID (*exit)(LosTaskCB *taskCB); + UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout); + VOID (*wake)(LosTaskCB *taskCB); + BOOL (*schedParamModify)(LosTaskCB *taskCB, const SchedParam *param); + UINT32 (*schedParamGet)(const LosTaskCB *taskCB, SchedParam *param); + UINT32 (*delay)(LosTaskCB *taskCB, UINT64 waitTime); + VOID (*yield)(LosTaskCB *taskCB); + UINT32 (*suspend)(LosTaskCB *taskCB); + UINT32 (*resume)(LosTaskCB *taskCB, BOOL *needSched); + UINT64 (*deadlineGet)(const LosTaskCB *taskCB); + VOID (*timeSliceUpdate)(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); + INT32 (*schedParamCompare)(const SchedPolicy *sp1, const SchedPolicy *sp2); + VOID (*priorityInheritance)(LosTaskCB *owner, const SchedParam *param); + VOID (*priorityRestore)(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); +} SchedOps; /** * @ingroup los_sched @@ -283,23 +341,31 @@ VOID OsSchedRunQueInit(VOID); */ #define OS_TASK_STATUS_EXIT 0x0100U +#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ + OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The delayed operation of this task is frozen. + */ +#define OS_TASK_STATUS_FROZEN 0x0200U + #define OS_TCB_NAME_LEN 32 -typedef struct { +typedef struct TagTaskCB { VOID *stackPointer; /**< Task stack pointer */ UINT16 taskStatus; /**< Task status */ - /* The scheduling */ - UINT16 basePrio; - UINT16 priority; /**< Task priority */ - UINT16 policy; UINT64 startTime; /**< The start time of each phase of task */ UINT64 waitTime; /**< Task delay time, tick number */ UINT64 irqStartTime; /**< Interrupt start time */ UINT32 irqUsedTime; /**< Interrupt consumption time */ - UINT32 initTimeSlice; /**< Task init time slice */ INT32 timeSlice; /**< Task remaining time slice */ SortLinkList sortList; /**< Task sortlink node */ + const SchedOps *ops; + SchedPolicy sp; UINT32 stackSize; /**< Task stack size */ UINTPTR topOfStack; /**< Task stack top */ @@ -314,8 +380,6 @@ typedef struct { LOS_DL_LIST threadList; /**< thread list */ UINT32 eventMask; /**< Event mask */ UINT32 eventMode; /**< Event mode */ - UINT32 priBitMap; /**< BitMap for recording the change of task priority, - the priority can not be greater than 31 */ #ifdef LOSCFG_KERNEL_CPUP OsCpupBase taskCpup; /**< task cpu usage */ #endif @@ -403,7 +467,7 @@ STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread) ArchCurrUserTaskSet(thread); } -STATIC INLINE VOID OsSchedIrqUpdateUsedTime(VOID) +STATIC INLINE VOID OsSchedIrqUsedTimeUpdate(VOID) { LosTaskCB *runTask = OsCurrTaskGet(); runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime; @@ -416,14 +480,14 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID) } #ifdef LOSCFG_KERNEL_SMP -STATIC INLINE VOID FindIdleRunQue(UINT16 *idleCpuid) +STATIC INLINE VOID IdleRunqueueFind(UINT16 *idleCpuid) { - SchedRunQue *idleRq = OsSchedRunQueByID(0); - UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->taskSortLink); + SchedRunqueue *idleRq = OsSchedRunqueueByID(0); + UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->timeoutQueue); UINT16 cpuid = 1; do { - SchedRunQue *rq = OsSchedRunQueByID(cpuid); - UINT32 temp = OsGetSortLinkNodeNum(&rq->taskSortLink); + SchedRunqueue *rq = OsSchedRunqueueByID(cpuid); + UINT32 temp = OsGetSortLinkNodeNum(&rq->timeoutQueue); if (nodeNum > temp) { *idleCpuid = cpuid; nodeNum = temp; @@ -433,20 +497,20 @@ STATIC INLINE VOID FindIdleRunQue(UINT16 *idleCpuid) } #endif -STATIC INLINE VOID OsSchedAddTask2TimeList(LosTaskCB *taskCB, UINT64 responseTime) +STATIC INLINE VOID OsSchedTimeoutQueueAdd(LosTaskCB *taskCB, UINT64 responseTime) { #ifdef LOSCFG_KERNEL_SMP UINT16 cpuid = AFFI_MASK_TO_CPUID(taskCB->cpuAffiMask); if (cpuid >= LOSCFG_KERNEL_CORE_NUM) { cpuid = 0; - FindIdleRunQue(&cpuid); + IdleRunqueueFind(&cpuid); } #else UINT16 cpuid = 0; #endif - SchedRunQue *rq = OsSchedRunQueByID(cpuid); - OsAdd2SortLink(&rq->taskSortLink, &taskCB->sortList, responseTime, cpuid); + SchedRunqueue *rq = OsSchedRunqueueByID(cpuid); + OsAdd2SortLink(&rq->timeoutQueue, &taskCB->sortList, responseTime, cpuid); #ifdef LOSCFG_KERNEL_SMP if ((cpuid != ArchCurrCpuid()) && (responseTime < rq->responseTime)) { rq->schedFlag |= INT_PEND_TICK; @@ -455,22 +519,22 @@ STATIC INLINE VOID OsSchedAddTask2TimeList(LosTaskCB *taskCB, UINT64 responseTim #endif } -STATIC INLINE VOID OsSchedDeTaskFromTimeList(LosTaskCB *taskCB) +STATIC INLINE VOID OsSchedTimeoutQueueDelete(LosTaskCB *taskCB) { SortLinkList *node = &taskCB->sortList; #ifdef LOSCFG_KERNEL_SMP - SchedRunQue *rq = OsSchedRunQueByID(node->cpuid); + SchedRunqueue *rq = OsSchedRunqueueByID(node->cpuid); #else - SchedRunQue *rq = OsSchedRunQueByID(0); + SchedRunqueue *rq = OsSchedRunqueueByID(0); #endif UINT64 oldResponseTime = GET_SORTLIST_VALUE(node); - OsDeleteFromSortLink(&rq->taskSortLink, node); + OsDeleteFromSortLink(&rq->timeoutQueue, node); if (oldResponseTime <= rq->responseTime) { rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; } } -STATIC INLINE UINT32 OsSchedAdjustTaskFromTimeList(LosTaskCB *taskCB, UINT64 responseTime) +STATIC INLINE UINT32 OsSchedTimeoutQueueAdjust(LosTaskCB *taskCB, UINT64 responseTime) { UINT32 ret; SortLinkList *node = &taskCB->sortList; @@ -479,14 +543,57 @@ STATIC INLINE UINT32 OsSchedAdjustTaskFromTimeList(LosTaskCB *taskCB, UINT64 res #else UINT16 cpuid = 0; #endif - SchedRunQue *rq = OsSchedRunQueByID(cpuid); - ret = OsSortLinkAdjustNodeResponseTime(&rq->taskSortLink, node, responseTime); + SchedRunqueue *rq = OsSchedRunqueueByID(cpuid); + ret = OsSortLinkAdjustNodeResponseTime(&rq->timeoutQueue, node, responseTime); if (ret == LOS_OK) { rq->schedFlag |= INT_PEND_TICK; } return ret; } +STATIC INLINE VOID SchedTaskFreeze(LosTaskCB *taskCB) +{ + UINT64 responseTime; + + if (!OsIsPmMode()) { + return; + } + + if (!(taskCB->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY))) { + return; + } + + responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); + OsSchedTimeoutQueueDelete(taskCB); + SET_SORTLIST_VALUE(&taskCB->sortList, responseTime); + taskCB->taskStatus |= OS_TASK_STATUS_FROZEN; + return; +} + +STATIC INLINE VOID SchedTaskUnfreeze(LosTaskCB *taskCB) +{ + UINT64 currTime, responseTime; + + if (!(taskCB->taskStatus & OS_TASK_STATUS_FROZEN)) { + return; + } + + taskCB->taskStatus &= ~OS_TASK_STATUS_FROZEN; + currTime = OsGetCurrSchedTimeCycle(); + responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); + if (responseTime > currTime) { + OsSchedTimeoutQueueAdd(taskCB, responseTime); + return; + } + + SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); + if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { + LOS_ListDelete(&taskCB->pendList); + } + taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; + return; +} + /* * Schedule flag, one bit represents one core. * This flag is used to prevent kernel scheduling before OSStartToRun. @@ -499,24 +606,59 @@ STATIC INLINE UINT32 OsSchedAdjustTaskFromTimeList(LosTaskCB *taskCB, UINT64 res g_taskScheduled &= ~(1U << (cpuid)); \ } while (0); -VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask); -VOID OsSchedResetSchedResponseTime(UINT64 responseTime); +STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq) +{ + LosTaskCB *newTask = NULL; + UINT32 baseBitmap = rq->queueBitmap; +#ifdef LOSCFG_KERNEL_SMP + UINT32 cpuid = ArchCurrCpuid(); +#endif + + while (baseBitmap) { + UINT32 basePrio = CLZ(baseBitmap); + HPFQueue *queueList = &rq->queueList[basePrio]; + UINT32 bitmap = queueList->queueBitmap; + while (bitmap) { + UINT32 priority = CLZ(bitmap); + LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &queueList->priQueList[priority], LosTaskCB, pendList) { +#ifdef LOSCFG_KERNEL_SMP + if (newTask->cpuAffiMask & (1U << cpuid)) { +#endif + return newTask; +#ifdef LOSCFG_KERNEL_SMP + } +#endif + } + bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1)); + } + baseBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - basePrio - 1)); + } + + return NULL; +} + +VOID HPFSchedPolicyInit(SchedRunqueue *rq); +VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, const TSK_INIT_PARAM_S *param); +VOID HPFProcessDefaultSchedParamGet(SchedParam *param); + +VOID IdleTaskSchedParamInit(LosTaskCB *taskCB); + +INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2); +VOID OsSchedPriorityInheritance(LosTaskCB *owner, const SchedParam *param); +UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, const TSK_INIT_PARAM_S *param); +VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param); + +VOID OsSchedResponseTimeReset(UINT64 responseTime); VOID OsSchedToUserReleaseLock(VOID); -VOID OsSchedTaskDeQueue(LosTaskCB *taskCB); -VOID OsSchedTaskEnQueue(LosTaskCB *taskCB); -UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched); -VOID OsSchedTaskWake(LosTaskCB *resumedTask); -BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priority); -BOOL OsSchedModifyProcessSchedParam(UINT32 pid, UINT16 policy, UINT16 priority); -VOID OsSchedSuspend(LosTaskCB *taskCB); -BOOL OsSchedResume(LosTaskCB *taskCB); -VOID OsSchedDelay(LosTaskCB *runTask, UINT64 waitTime); -VOID OsSchedYield(VOID); -VOID OsSchedTaskExit(LosTaskCB *taskCB); VOID OsSchedTick(VOID); UINT32 OsSchedInit(VOID); VOID OsSchedStart(VOID); +VOID OsSchedRunqueueIdleInit(UINT32 idleTaskID); +VOID OsSchedRunqueueInit(VOID); + /* * This function simply picks the next task and switches to it. * Current task needs to already be in the right state or the right diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index f5e399e4..5057e10f 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -73,7 +73,7 @@ extern SPIN_LOCK_S g_taskSpin; * * The task control block is unused. */ -#define OS_TASK_STATUS_UNUSED 0x0200U +#define OS_TASK_STATUS_UNUSED 0x0400U /** * @ingroup los_task @@ -81,7 +81,7 @@ extern SPIN_LOCK_S g_taskSpin; * * The task is joinable. */ -#define OS_TASK_FLAG_PTHREAD_JOIN 0x0400U +#define OS_TASK_FLAG_PTHREAD_JOIN 0x0800U /** * @ingroup los_task @@ -89,7 +89,7 @@ extern SPIN_LOCK_S g_taskSpin; * * The task is user mode task. */ -#define OS_TASK_FLAG_USER_MODE 0x0800U +#define OS_TASK_FLAG_USER_MODE 0x1000U /** * @ingroup los_task @@ -97,7 +97,7 @@ extern SPIN_LOCK_S g_taskSpin; * * The task is system-level task, like idle, swtmr and etc. */ -#define OS_TASK_FLAG_SYSTEM_TASK 0x1000U +#define OS_TASK_FLAG_SYSTEM_TASK 0x2000U /** * @ingroup los_task @@ -105,7 +105,7 @@ extern SPIN_LOCK_S g_taskSpin; * * The task is no-delete system task, like resourceTask. */ -#define OS_TASK_FLAG_NO_DELETE 0x2000U +#define OS_TASK_FLAG_NO_DELETE 0x4000U /** * @ingroup los_task @@ -113,15 +113,7 @@ extern SPIN_LOCK_S g_taskSpin; * * Kills the thread during process exit. */ -#define OS_TASK_FLAG_EXIT_KILL 0x4000U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The delayed operation of this task is frozen. - */ -#define OS_TASK_FLAG_FREEZE 0x8000U +#define OS_TASK_FLAG_EXIT_KILL 0x8000U /** * @ingroup los_task diff --git a/kernel/base/ipc/los_event.c b/kernel/base/ipc/los_event.c index 635283cb..dc55aa25 100644 --- a/kernel/base/ipc/los_event.c +++ b/kernel/base/ipc/los_event.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -147,7 +147,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM runTask->eventMode = mode; runTask->taskEvent = eventCB; OsTaskWaitSetPendMask(OS_TASK_WAIT_EVENT, eventMask, timeout); - ret = OsSchedTaskWait(&eventCB->stEventList, timeout, TRUE); + ret = runTask->ops->wait(runTask, &eventCB->stEventList, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { return LOS_ERRNO_EVENT_READ_TIMEOUT; } @@ -185,7 +185,7 @@ LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT resumedTask->taskEvent = NULL; OsTaskWakeClearPendMask(resumedTask); - OsSchedTaskWake(resumedTask); + resumedTask->ops->wake(resumedTask); } return exitFlag; diff --git a/kernel/base/ipc/los_futex.c b/kernel/base/ipc/los_futex.c index 44de7a5b..384bb483 100644 --- a/kernel/base/ipc/los_futex.c +++ b/kernel/base/ipc/los_futex.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -118,10 +118,10 @@ STATIC VOID OsFutexShowTaskNodeAttr(const LOS_DL_LIST *futexList) lastNode = OS_FUTEX_FROM_QUEUELIST(queueList); if (!LOS_ListEmpty(&(lastNode->pendList))) { taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(lastNode->pendList))); - PRINTK(" %u(%u) ->", taskCB->taskID, taskCB->priority); + PRINTK(" %u ->", taskCB->taskID); } else { taskCB = LOS_DL_LIST_ENTRY(lastNode, LosTaskCB, futex); - PRINTK(" %u(%d) ->", taskCB->taskID, -1); + PRINTK(" %u ->", taskCB->taskID); } queueList = queueList->pstNext; if (queueList == &tempNode->queueList) { @@ -336,20 +336,19 @@ STATIC INT32 OsFutexInsertFindFormBackToFront(LOS_DL_LIST *queueList, const LosT { LOS_DL_LIST *listHead = queueList; LOS_DL_LIST *listTail = queueList->pstPrev; - FutexNode *tempNode = NULL; - LosTaskCB *taskTail = NULL; for (; listHead != listTail; listTail = listTail->pstPrev) { - tempNode = OS_FUTEX_FROM_QUEUELIST(listTail); + FutexNode *tempNode = OS_FUTEX_FROM_QUEUELIST(listTail); tempNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(tempNode, NULL, FALSE); if (tempNode == NULL) { return LOS_NOK; } - taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList))); - if (runTask->priority >= taskTail->priority) { + LosTaskCB *taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList))); + INT32 ret = OsSchedParamCompare(runTask, taskTail); + if (ret >= 0) { LOS_ListHeadInsert(&(tempNode->queueList), &(node->queueList)); return LOS_OK; - } else if (runTask->priority < taskTail->priority) { + } else { if (listTail->pstPrev == listHead) { LOS_ListTailInsert(&(tempNode->queueList), &(node->queueList)); return LOS_OK; @@ -364,26 +363,25 @@ STATIC INT32 OsFutexInsertFindFromFrontToBack(LOS_DL_LIST *queueList, const LosT { LOS_DL_LIST *listHead = queueList; LOS_DL_LIST *listTail = queueList->pstPrev; - FutexNode *tempNode = NULL; - LosTaskCB *taskHead = NULL; for (; listHead != listTail; listHead = listHead->pstNext) { - tempNode = OS_FUTEX_FROM_QUEUELIST(listHead); + FutexNode *tempNode = OS_FUTEX_FROM_QUEUELIST(listHead); tempNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(tempNode, NULL, FALSE); if (tempNode == NULL) { return LOS_NOK; } - taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList))); + LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList))); /* High priority comes before low priority, * in the case of the same priority, after the current node */ - if (runTask->priority >= taskHead->priority) { + INT32 ret = OsSchedParamCompare(runTask, taskHead); + if (ret >= 0) { if (listHead->pstNext == listTail) { LOS_ListHeadInsert(&(tempNode->queueList), &(node->queueList)); return LOS_OK; } continue; - } else if (runTask->priority < taskHead->priority) { + } else { LOS_ListTailInsert(&(tempNode->queueList), &(node->queueList)); return LOS_OK; } @@ -414,10 +412,9 @@ STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node, { LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&((*firstNode)->pendList))); LOS_DL_LIST *queueList = &((*firstNode)->queueList); - FutexNode *tailNode = NULL; - LosTaskCB *taskTail = NULL; - if (run->priority < taskHead->priority) { + INT32 ret1 = OsSchedParamCompare(run, taskHead); + if (ret1 < 0) { /* The one with the highest priority is inserted at the top of the queue */ LOS_ListTailInsert(queueList, &(node->queueList)); OsFutexReplaceQueueListHeadNode(*firstNode, node); @@ -425,16 +422,16 @@ STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node, return LOS_OK; } - if (LOS_ListEmpty(queueList) && (run->priority >= taskHead->priority)) { + if (LOS_ListEmpty(queueList) && (ret1 >= 0)) { /* Insert the next position in the queue with equal priority */ LOS_ListHeadInsert(queueList, &(node->queueList)); return LOS_OK; } - tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList)); - taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tailNode->pendList))); - if ((run->priority >= taskTail->priority) || - ((run->priority - taskHead->priority) > (taskTail->priority - run->priority))) { + FutexNode *tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList)); + LosTaskCB *taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tailNode->pendList))); + INT32 ret2 = OsSchedParamCompare(taskTail, run); + if ((ret2 <= 0) || (ret1 > ret2)) { return OsFutexInsertFindFormBackToFront(queueList, run, node); } @@ -569,7 +566,7 @@ STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const return LOS_OK; } -STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const UINT32 val, const UINT32 timeOut) +STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const UINT32 val, const UINT32 timeout) { INT32 futexRet; UINT32 intSave, lockVal; @@ -600,9 +597,9 @@ STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const } SCHEDULER_LOCK(intSave); - OsTaskWaitSetPendMask(OS_TASK_WAIT_FUTEX, futexKey, timeOut); - OsSchedTaskWait(&(node->pendList), timeOut, FALSE); OsSchedLock(); + OsTaskWaitSetPendMask(OS_TASK_WAIT_FUTEX, futexKey, timeout); + taskCB->ops->wait(taskCB, &(node->pendList), timeout); LOS_SpinUnlock(&g_taskSpin); futexRet = OsFutexUnlock(&hashNode->listLock); @@ -639,17 +636,17 @@ EXIT_UNLOCK_ERR: INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime) { INT32 ret; - UINT32 timeOut = LOS_WAIT_FOREVER; + UINT32 timeout = LOS_WAIT_FOREVER; ret = OsFutexWaitParamCheck(userVaddr, flags, absTime); if (ret) { return ret; } if (absTime != LOS_WAIT_FOREVER) { - timeOut = OsNS2Tick((UINT64)absTime * OS_SYS_NS_PER_US); + timeout = OsNS2Tick((UINT64)absTime * OS_SYS_NS_PER_US); } - return OsFutexWaitTask(userVaddr, flags, val, timeOut); + return OsFutexWaitTask(userVaddr, flags, val, timeout); } STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags) @@ -693,7 +690,7 @@ STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNum node = *nextNode; taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(node->pendList))); OsTaskWakeClearPendMask(taskCB); - OsSchedTaskWake(taskCB); + taskCB->ops->wake(taskCB); *wakeAny = TRUE; *nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&(node->queueList))); if (node != headNode) { diff --git a/kernel/base/ipc/los_mux.c b/kernel/base/ipc/los_mux.c index 61ee89e0..fa4a67b8 100644 --- a/kernel/base/ipc/los_mux.c +++ b/kernel/base/ipc/los_mux.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -257,40 +257,36 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex) return LOS_OK; } -STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask, LosTaskCB *owner) +STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask) { - if ((owner->priority > runTask->priority) && (mutex->attr.protocol == LOS_MUX_PRIO_INHERIT)) { - LOS_BitmapSet(&(owner->priBitMap), owner->priority); - (VOID)OsSchedModifyTaskSchedParam(owner, owner->policy, runTask->priority); + if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { + return; + } + + SchedParam param = { 0 }; + LosTaskCB *owner = (LosTaskCB *)mutex->owner; + INT32 ret = OsSchedParamCompare(owner, runTask); + if (ret > 0) { + runTask->ops->schedParamGet(runTask, ¶m); + owner->ops->priorityInheritance(owner, ¶m); } } -VOID OsMuxBitmapRestore(const LosMux *mutex, const LosTaskCB *taskCB, LosTaskCB *owner) +VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask) { - UINT16 bitMapPri; - if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { return; } - if (owner->priority >= taskCB->priority) { - bitMapPri = LOS_LowBitGet(owner->priBitMap); - if (bitMapPri != LOS_INVALID_BIT_INDEX) { - LOS_BitmapClr(&(owner->priBitMap), bitMapPri); - OsSchedModifyTaskSchedParam(owner, owner->policy, bitMapPri); - } - } else { - if (LOS_HighBitGet(owner->priBitMap) != taskCB->priority) { - LOS_BitmapClr(&(owner->priBitMap), taskCB->priority); - } - } + SchedParam param = { 0 }; + LosTaskCB *owner = (LosTaskCB *)mutex->owner; + runTask->ops->schedParamGet(runTask, ¶m); + owner->ops->priorityRestore(owner, list, ¶m); } STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) { UINT32 ret; - LOS_DL_LIST *node = NULL; - LosTaskCB *owner = NULL; if ((mutex->muxList.pstPrev == NULL) || (mutex->muxList.pstNext == NULL)) { /* This is for mutex macro initialization. */ @@ -303,9 +299,11 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) mutex->muxCount++; mutex->owner = (VOID *)runTask; LOS_ListTailInsert(&runTask->lockList, &mutex->holdList); - if ((mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) && (runTask->priority > mutex->attr.prioceiling)) { - LOS_BitmapSet(&runTask->priBitMap, runTask->priority); - (VOID)OsSchedModifyTaskSchedParam(runTask, runTask->policy, mutex->attr.prioceiling); + if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { + SchedParam param = { 0 }; + runTask->ops->schedParamGet(runTask, ¶m); + param.priority = mutex->attr.prioceiling; + runTask->ops->priorityInheritance(runTask, ¶m); } return LOS_OK; } @@ -323,27 +321,23 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) return LOS_EDEADLK; } - OsMuxBitmapSet(mutex, runTask, (LosTaskCB *)mutex->owner); + OsMuxBitmapSet(mutex, runTask); - owner = (LosTaskCB *)mutex->owner; runTask->taskMux = (VOID *)mutex; - node = OsSchedLockPendFindPos(runTask, &mutex->muxList); + LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &mutex->muxList); if (node == NULL) { ret = LOS_NOK; return ret; } OsTaskWaitSetPendMask(OS_TASK_WAIT_MUTEX, (UINTPTR)mutex, timeout); - ret = OsSchedTaskWait(node, timeout, TRUE); + ret = runTask->ops->wait(runTask, node, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { + OsMuxBitmapRestore(mutex, NULL, runTask); runTask->taskMux = NULL; ret = LOS_ETIMEDOUT; } - if (timeout != LOS_WAIT_FOREVER) { - OsMuxBitmapRestore(mutex, runTask, owner); - } - return ret; } @@ -440,50 +434,23 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex) return ret; } -STATIC VOID OsMuxPostOpSub(LosTaskCB *taskCB, LosMux *mutex) -{ - LosTaskCB *pendedTask = NULL; - UINT16 bitMapPri; - - if (!LOS_ListEmpty(&mutex->muxList)) { - bitMapPri = LOS_HighBitGet(taskCB->priBitMap); - LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, (&mutex->muxList), LosTaskCB, pendList) { - if (bitMapPri != pendedTask->priority) { - LOS_BitmapClr(&taskCB->priBitMap, pendedTask->priority); - } - } - } - bitMapPri = LOS_LowBitGet(taskCB->priBitMap); - LOS_BitmapClr(&taskCB->priBitMap, bitMapPri); - (VOID)OsSchedModifyTaskSchedParam((LosTaskCB *)mutex->owner, ((LosTaskCB *)mutex->owner)->policy, bitMapPri); -} - STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) { - LosTaskCB *resumedTask = NULL; - if (LOS_ListEmpty(&mutex->muxList)) { LOS_ListDelete(&mutex->holdList); mutex->owner = NULL; return LOS_OK; } - resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList))); - if (mutex->attr.protocol == LOS_MUX_PRIO_INHERIT) { - if (resumedTask->priority > taskCB->priority) { - if (LOS_HighBitGet(taskCB->priBitMap) != resumedTask->priority) { - LOS_BitmapClr(&taskCB->priBitMap, resumedTask->priority); - } - } else if (taskCB->priBitMap != 0) { - OsMuxPostOpSub(taskCB, mutex); - } - } + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList))); + OsMuxBitmapRestore(mutex, &mutex->muxList, resumedTask); + mutex->muxCount = 1; mutex->owner = (VOID *)resumedTask; LOS_ListDelete(&mutex->holdList); LOS_ListTailInsert(&resumedTask->lockList, &mutex->holdList); OsTaskWakeClearPendMask(resumedTask); - OsSchedTaskWake(resumedTask); + resumedTask->ops->wake(resumedTask); resumedTask->taskMux = NULL; if (needSched != NULL) { *needSched = TRUE; @@ -494,8 +461,6 @@ STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) { - UINT16 bitMapPri; - if (mutex->magic != OS_MUX_MAGIC) { return LOS_EBADF; } @@ -517,11 +482,9 @@ UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) } if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { - bitMapPri = LOS_HighBitGet(taskCB->priBitMap); - if (bitMapPri != LOS_INVALID_BIT_INDEX) { - LOS_BitmapClr(&taskCB->priBitMap, bitMapPri); - (VOID)OsSchedModifyTaskSchedParam(taskCB, taskCB->policy, bitMapPri); - } + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + taskCB->ops->priorityRestore(taskCB, NULL, ¶m); } /* Whether a task block the mutex lock. */ diff --git a/kernel/base/ipc/los_queue.c b/kernel/base/ipc/los_queue.c index 5e01690e..705c1a9d 100644 --- a/kernel/base/ipc/los_queue.c +++ b/kernel/base/ipc/los_queue.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -258,15 +258,13 @@ STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout) { - LosQueueCB *queueCB = NULL; - LosTaskCB *resumedTask = NULL; UINT32 ret; UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType); UINT32 intSave; OsHookCall(LOS_HOOK_TYPE_QUEUE_READ, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, *bufferSize, timeout); SCHEDULER_LOCK(intSave); - queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize); if (ret != LOS_OK) { goto QUEUE_END; @@ -283,8 +281,9 @@ UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT goto QUEUE_END; } + LosTaskCB *runTask = OsCurrTaskGet(); OsTaskWaitSetPendMask(OS_TASK_WAIT_QUEUE, queueCB->queueID, timeout); - ret = OsSchedTaskWait(&queueCB->readWriteList[readWrite], timeout, TRUE); + ret = runTask->ops->wait(runTask, &queueCB->readWriteList[readWrite], timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { ret = LOS_ERRNO_QUEUE_TIMEOUT; goto QUEUE_END; @@ -296,9 +295,9 @@ UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize); if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) { - resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite])); + LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite])); OsTaskWakeClearPendMask(resumedTask); - OsSchedTaskWake(resumedTask); + resumedTask->ops->wake(resumedTask); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); LOS_Schedule(); diff --git a/kernel/base/ipc/los_rwlock.c b/kernel/base/ipc/los_rwlock.c index 36b03189..9b1a610a 100644 --- a/kernel/base/ipc/los_rwlock.c +++ b/kernel/base/ipc/los_rwlock.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -37,7 +37,6 @@ #include "los_exc.h" #include "los_sched_pri.h" - #ifdef LOSCFG_BASE_IPC_RWLOCK #define RWLOCK_COUNT_MASK 0x00FFFFFFU @@ -120,7 +119,7 @@ STATIC BOOL OsRwlockPriCompare(LosTaskCB *runTask, LOS_DL_LIST *rwList) { if (!LOS_ListEmpty(rwList)) { LosTaskCB *highestTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(rwList)); - if (runTask->priority < highestTask->priority) { + if (OsSchedParamCompare(runTask, highestTask) < 0) { return TRUE; } return FALSE; @@ -164,7 +163,7 @@ STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim * is lower than the first pended write task, current read task will be pended. */ LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->readList)); - ret = OsSchedTaskWait(node, timeout, TRUE); + ret = runTask->ops->wait(runTask, node, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { return LOS_ETIMEDOUT; } @@ -205,7 +204,7 @@ STATIC UINT32 OsRwlockWrPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim * write task will be pended. */ LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->writeList)); - ret = OsSchedTaskWait(node, timeout, TRUE); + ret = runTask->ops->wait(runTask, node, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { ret = LOS_ETIMEDOUT; } @@ -355,7 +354,7 @@ STATIC UINT32 OsRwlockGetMode(LOS_DL_LIST *readList, LOS_DL_LIST *writeList) } LosTaskCB *pendedReadTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(readList)); LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(writeList)); - if (pendedWriteTask->priority <= pendedReadTask->priority) { + if (OsSchedParamCompare(pendedWriteTask, pendedReadTask) <= 0) { return RWLOCK_WRITEFIRST_MODE; } return RWLOCK_READFIRST_MODE; @@ -365,7 +364,6 @@ STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched) { UINT32 rwlockMode; LosTaskCB *resumedTask = NULL; - UINT16 pendedWriteTaskPri; rwlock->rwCount = 0; rwlock->writeOwner = NULL; @@ -378,29 +376,29 @@ STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched) resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList))); rwlock->rwCount = -1; rwlock->writeOwner = (VOID *)resumedTask; - OsSchedTaskWake(resumedTask); + resumedTask->ops->wake(resumedTask); if (needSched != NULL) { *needSched = TRUE; } return LOS_OK; } - /* In this case, rwlock will wake the valid pended read task. */ - if (rwlockMode == RWLOCK_READFIRST_MODE) { - pendedWriteTaskPri = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList)))->priority; - } - resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList))); + rwlock->rwCount = 1; - OsSchedTaskWake(resumedTask); + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList))); + resumedTask->ops->wake(resumedTask); while (!LOS_ListEmpty(&(rwlock->readList))) { resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList))); - if ((rwlockMode == RWLOCK_READFIRST_MODE) && (resumedTask->priority >= pendedWriteTaskPri)) { - break; + if (rwlockMode == RWLOCK_READFIRST_MODE) { + LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList))); + if (OsSchedParamCompare(resumedTask, pendedWriteTask) >= 0) { + break; + } } if (rwlock->rwCount == INT8_MAX) { return EINVAL; } rwlock->rwCount++; - OsSchedTaskWake(resumedTask); + resumedTask->ops->wake(resumedTask); } if (needSched != NULL) { *needSched = TRUE; diff --git a/kernel/base/ipc/los_sem.c b/kernel/base/ipc/los_sem.c index f6633b92..31d484a1 100644 --- a/kernel/base/ipc/los_sem.c +++ b/kernel/base/ipc/los_sem.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -225,7 +225,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout); OsTaskWaitSetPendMask(OS_TASK_WAIT_SEM, semPended->semID, timeout); - retErr = OsSchedTaskWait(&semPended->semList, timeout, TRUE); + retErr = runTask->ops->wait(runTask, &semPended->semList, timeout); if (retErr == LOS_ERRNO_TSK_TIMEOUT) { retErr = LOS_ERRNO_SEM_TIMEOUT; } @@ -237,10 +237,8 @@ OUT: LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) { - LosSemCB *semPosted = NULL; LosTaskCB *resumedTask = NULL; - - semPosted = GET_SEM(semHandle); + LosSemCB *semPosted = GET_SEM(semHandle); if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) { return LOS_ERRNO_SEM_INVALID; } @@ -254,7 +252,7 @@ LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) if (!LOS_ListEmpty(&semPosted->semList)) { resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList))); OsTaskWakeClearPendMask(resumedTask); - OsSchedTaskWake(resumedTask); + resumedTask->ops->wake(resumedTask); if (needSched != NULL) { *needSched = TRUE; } diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index dd179d86..ba50f1a7 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -129,7 +129,7 @@ STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo) if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, signo)) { OsMoveTmpInfoToUnbInfo(sigcb, signo); OsTaskWakeClearPendMask(taskCB); - OsSchedTaskWake(taskCB); + taskCB->ops->wake(taskCB); OsSigEmptySet(&sigcb->sigwaitmask); } } @@ -152,19 +152,19 @@ STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo) break; case OS_TASK_WAIT_JOIN: OsTaskWakeClearPendMask(taskCB); - OsSchedTaskWake(taskCB); + taskCB->ops->wake(taskCB); break; case OS_TASK_WAIT_SIGNAL: OsSigWaitTaskWake(taskCB, signo); break; case OS_TASK_WAIT_LITEIPC: OsTaskWakeClearPendMask(taskCB); - OsSchedTaskWake(taskCB); + taskCB->ops->wake(taskCB); break; case OS_TASK_WAIT_FUTEX: OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); OsTaskWakeClearPendMask(taskCB); - OsSchedTaskWake(taskCB); + taskCB->ops->wake(taskCB); break; default: break; @@ -567,7 +567,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout) sigcb->sigwaitmask |= *set; OsTaskWaitSetPendMask(OS_TASK_WAIT_SIGNAL, sigcb->sigwaitmask, timeout); - ret = OsSchedTaskWait(&sigcb->waitList, timeout, TRUE); + ret = task->ops->wait(task, &sigcb->waitList, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { ret = -EAGAIN; } diff --git a/kernel/base/misc/task_shellcmd.c b/kernel/base/misc/task_shellcmd.c index 1d680b66..a83951be 100644 --- a/kernel/base/misc/task_shellcmd.c +++ b/kernel/base/misc/task_shellcmd.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -63,45 +63,44 @@ #define OS_PROCESS_CPUP_LEN (g_processMaxNum * sizeof(CPUP_INFO_S)) #define OS_PROCESS_AND_TASK_CPUP_LEN ((g_processMaxNum + g_taskMaxNum) * sizeof(CPUP_INFO_S)) #define OS_PROCESS_CPUP_ALLINFO_LEN (OS_PROCESS_AND_TASK_CPUP_LEN * 3) +STATIC VOID TaskCpupInfoBaseGet(UINTPTR base, const CPUP_INFO_S **, const CPUP_INFO_S **, const CPUP_INFO_S **); +STATIC VOID ProcessCpupInfoBaseGet(UINTPTR base, const CPUP_INFO_S **, const CPUP_INFO_S **, const CPUP_INFO_S **); #else #define OS_PROCESS_CPUP_ALLINFO_LEN 0 #endif #define OS_PROCESS_ALL_INFO_LEN (g_processMaxNum * (sizeof(LosProcessCB) + sizeof(UINT32)) + \ OS_PROCESS_CPUP_ALLINFO_LEN + OS_PROCESS_UID_INFO_LEN) -#ifdef LOSCFG_KERNEL_CPUP -LITE_OS_SEC_BSS STATIC CPUP_INFO_S *processCpupAll = NULL; -LITE_OS_SEC_BSS STATIC CPUP_INFO_S *processCpup10s = NULL; -LITE_OS_SEC_BSS STATIC CPUP_INFO_S *processCpup1s = NULL; -LITE_OS_SEC_BSS STATIC CPUP_INFO_S *taskCpupAll = NULL; -LITE_OS_SEC_BSS STATIC CPUP_INFO_S *taskCpup10s = NULL; -LITE_OS_SEC_BSS STATIC CPUP_INFO_S *taskCpup1s = NULL; -#endif - -STATIC UINT32 *taskWaterLine = NULL; #define OS_INVALID_SEM_ID 0xFFFFFFFF #define OS_TASK_WATER_LINE_SIZE (g_taskMaxNum * sizeof(UINT32)) #define OS_TASK_INFO_LEN (g_taskMaxNum * sizeof(LosTaskCB)) -#define OS_TASK_ALL_INFO_LEN (g_taskMaxNum * (sizeof(LosTaskCB) + sizeof(UINT32))) +#define OS_TASK_SCHED_INFO_LEN (g_taskMaxNum * sizeof(SchedParam)) +#define OS_TASK_ALL_INFO_LEN (g_taskMaxNum * (sizeof(LosTaskCB) + sizeof(UINT32) + sizeof(SchedParam))) +#undef SHOW #ifdef LOSCFG_FS_VFS #if defined(LOSCFG_BLACKBOX) && defined(LOSCFG_SAVE_EXCINFO) #define SaveExcInfo(arg, ...) WriteExcInfoToBuf(arg, ##__VA_ARGS__) #else #define SaveExcInfo(arg, ...) #endif -#define PROCESS_INFO_SHOW(seqBuf, arg...) do { \ - if (seqBuf != NULL) { \ - (void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \ +#define SHOW(arg...) do { \ + if (seqBuf != NULL) { \ + (void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \ } else { \ PRINTK(arg); \ } \ SaveExcInfo(arg); \ } while (0) #else -#define PROCESS_INFO_SHOW(seqBuf, arg...) PRINTK(arg) +#define SHOW(arg...) PRINTK(arg) #endif +#define VM_INDEX PROCESS_VM_INDEX +#define SM_INDEX PROCESS_SM_INDEX +#define PM_INDEX PROCESS_PM_INDEX +#define CPUP_MULT LOS_CPUP_PRECISION_MULT + STATIC UINT8 *ConvertProcessModeToString(UINT16 mode) { if (mode == OS_KERNEL_MODE) { @@ -142,77 +141,72 @@ STATIC UINT8 *ConvertProcessStatusToString(UINT16 status) STATIC VOID ProcessInfoTitle(VOID *seqBuf, UINT16 flag) { - PROCESS_INFO_SHOW(seqBuf, "\r\n PID PPID PGID UID Mode Status Policy Priority MTID TTotal"); + SHOW("\r\n PID PPID PGID UID Mode Status Policy Priority MTID TTotal"); if (flag & OS_PROCESS_INFO_ALL) { if (flag & OS_PROCESS_MEM_INFO) { - PROCESS_INFO_SHOW(seqBuf, " VirtualMem ShareMem PhysicalMem"); + SHOW(" VirtualMem ShareMem PhysicalMem"); } #ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, " CPUUSE CPUUSE10s CPUUSE1s"); + SHOW(" CPUUSE CPUUSE10s CPUUSE1s"); #endif /* LOSCFG_KERNEL_CPUP */ } else { #ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, " CPUUSE10s"); + SHOW(" CPUUSE10s"); #endif /* LOSCFG_KERNEL_CPUP */ } - PROCESS_INFO_SHOW(seqBuf, " PName\n"); + SHOW(" PName\n"); } -STATIC VOID ProcessDataShow(const LosProcessCB *processCB, const INT32 *group, - const UINT32 *memArray, VOID *seqBuf, UINT16 flag) +STATIC VOID AllProcessDataShow(const LosProcessCB *pcbArray, const SchedParam *param, + UINTPTR cpupInfo, VOID *seqBuf, UINT16 flag) { - const UINT32 *procMemUsage = NULL; + const INT32 *group = (const INT32 *)((UINTPTR)pcbArray + OS_PROCESS_INFO_LEN); const INT32 *user = (const INT32 *)((UINTPTR)group + OS_PROCESS_GROUP_INFO_LEN); - UINT32 pid = processCB->processID; - PROCESS_INFO_SHOW(seqBuf, "%5u%6d%5d%6d%7s%8s%7s%9u%5d%7u", - pid, (INT32)processCB->parentProcessID, group[pid], user[pid], - ConvertProcessModeToString(processCB->processMode), - ConvertProcessStatusToString(processCB->processStatus), - ConvertSchedPolicyToString(LOS_SCHED_RR), OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio, - (INT32)processCB->threadGroupID, processCB->threadNumber); - - if (flag & OS_PROCESS_INFO_ALL) { - if (flag & OS_PROCESS_MEM_INFO) { - procMemUsage = &memArray[pid * PROCESS_VM_INDEX_MAX]; - PROCESS_INFO_SHOW(seqBuf, "%#11x%#9x%#12x", procMemUsage[PROCESS_VM_INDEX], procMemUsage[PROCESS_SM_INDEX], - procMemUsage[PROCESS_PM_INDEX]); - } -#ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, "%4u.%-2u%7u.%-2u%6u.%-2u ", - processCpupAll[pid].usage / LOS_CPUP_PRECISION_MULT, - processCpupAll[pid].usage % LOS_CPUP_PRECISION_MULT, - processCpup10s[pid].usage / LOS_CPUP_PRECISION_MULT, - processCpup10s[pid].usage % LOS_CPUP_PRECISION_MULT, - processCpup1s[pid].usage / LOS_CPUP_PRECISION_MULT, - processCpup1s[pid].usage % LOS_CPUP_PRECISION_MULT); -#endif /* LOSCFG_KERNEL_CPUP */ - } else { + const UINT32 *memArray = (const UINT32 *)((UINTPTR)pcbArray + OS_PROCESS_ALL_INFO_LEN); #ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, "%7u.%-2u ", - processCpup10s[pid].usage / LOS_CPUP_PRECISION_MULT, - processCpup10s[pid].usage % LOS_CPUP_PRECISION_MULT); -#endif /* LOSCFG_KERNEL_CPUP */ - } - PROCESS_INFO_SHOW(seqBuf, "%-32s\n", processCB->processName); -} + const CPUP_INFO_S *cpupAll = NULL; + const CPUP_INFO_S *cpup10s = NULL; + const CPUP_INFO_S *cpup1s = NULL; + ProcessCpupInfoBaseGet(cpupInfo, &cpupAll, &cpup10s, &cpup1s); +#else + (VOID)cpupInfo; +#endif -STATIC VOID AllProcessDataShow(const LosProcessCB *pcbArray, const INT32 *group, - const UINT32 *memArray, VOID *seqBuf, UINT16 flag) -{ for (UINT32 pid = 1; pid < g_processMaxNum; ++pid) { const LosProcessCB *processCB = pcbArray + pid; if (OsProcessIsUnused(processCB)) { continue; } - ProcessDataShow(processCB, group, memArray, seqBuf, flag); + SHOW("%5u%6d%5d%6d%7s%8s%7s%9u%5u%7u", pid, (INT32)processCB->parentProcessID, group[pid], user[pid], + ConvertProcessModeToString(processCB->processMode), ConvertProcessStatusToString(processCB->processStatus), + ConvertSchedPolicyToString(LOS_SCHED_RR), param[processCB->threadGroupID].basePrio, + processCB->threadGroupID, processCB->threadNumber); + + if (flag & OS_PROCESS_INFO_ALL) { + if (flag & OS_PROCESS_MEM_INFO) { + const UINT32 *memUsage = &memArray[pid * PROCESS_VM_INDEX_MAX]; + SHOW("%#11x%#9x%#12x", memUsage[VM_INDEX], memUsage[SM_INDEX], memUsage[PM_INDEX]); + } +#ifdef LOSCFG_KERNEL_CPUP + SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ", cpupAll[pid].usage / CPUP_MULT, cpupAll[pid].usage % CPUP_MULT, + cpup10s[pid].usage / CPUP_MULT, cpup10s[pid].usage % CPUP_MULT, + cpup1s[pid].usage / CPUP_MULT, cpup1s[pid].usage % CPUP_MULT); +#endif /* LOSCFG_KERNEL_CPUP */ + } else { +#ifdef LOSCFG_KERNEL_CPUP + SHOW("%7u.%-2u ", cpup10s[pid].usage / CPUP_MULT, cpup10s[pid].usage % CPUP_MULT); +#endif /* LOSCFG_KERNEL_CPUP */ + } + SHOW("%-32s\n", processCB->processName); } } #ifdef LOSCFG_KERNEL_VM -STATIC VOID ProcessMemUsageGet(UINT32 *memArray, LosProcessCB *pcbArray) +STATIC VOID ProcessMemUsageGet(LosProcessCB *pcbArray) { UINT32 intSave, memUsed; + UINT32 *memArray = (UINT32 *)((UINTPTR)pcbArray + OS_PROCESS_ALL_INFO_LEN); for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) { const LosProcessCB *processCB = g_processCBArray + pid; @@ -230,20 +224,20 @@ STATIC VOID ProcessMemUsageGet(UINT32 *memArray, LosProcessCB *pcbArray) /* Process memory usage statistics, idle task defaults to 0 */ if (pid == OsGetIdleProcessID()) { - proMemUsage[PROCESS_VM_INDEX] = 0; - proMemUsage[PROCESS_SM_INDEX] = 0; - proMemUsage[PROCESS_PM_INDEX] = 0; + proMemUsage[VM_INDEX] = 0; + proMemUsage[SM_INDEX] = 0; + proMemUsage[PM_INDEX] = 0; } else if (vmSpace == LOS_GetKVmSpace()) { - (VOID)OsShellCmdProcessPmUsage(vmSpace, &proMemUsage[PROCESS_SM_INDEX], &proMemUsage[PROCESS_PM_INDEX]); - proMemUsage[PROCESS_VM_INDEX] = proMemUsage[PROCESS_PM_INDEX]; + (VOID)OsShellCmdProcessPmUsage(vmSpace, &proMemUsage[SM_INDEX], &proMemUsage[PM_INDEX]); + proMemUsage[VM_INDEX] = proMemUsage[PM_INDEX]; } else { memUsed = OsShellCmdProcessVmUsage(vmSpace); if (memUsed == 0) { pcbArray[pid].processStatus = OS_PROCESS_FLAG_UNUSED; continue; } - proMemUsage[PROCESS_VM_INDEX] = memUsed; - memUsed = OsShellCmdProcessPmUsage(vmSpace, &proMemUsage[PROCESS_SM_INDEX], &proMemUsage[PROCESS_PM_INDEX]); + proMemUsage[VM_INDEX] = memUsed; + memUsed = OsShellCmdProcessPmUsage(vmSpace, &proMemUsage[SM_INDEX], &proMemUsage[PM_INDEX]); if (memUsed == 0) { pcbArray[pid].processStatus = OS_PROCESS_FLAG_UNUSED; } @@ -253,10 +247,12 @@ STATIC VOID ProcessMemUsageGet(UINT32 *memArray, LosProcessCB *pcbArray) #endif #define OS_TASK_STATUS_MASK 0x00FF -STATIC VOID ProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, LosTaskCB **tcbArray) +STATIC VOID ProcessInfoGet(LosProcessCB **pcbArray, LosTaskCB **tcbArray, SchedParam **schedParam) { - *group = (INT32 *)((UINTPTR)*pcbArray + OS_PROCESS_INFO_LEN); - INT32 *user = (INT32 *)((UINTPTR)*group + OS_PROCESS_GROUP_INFO_LEN); + INT32 *group = (INT32 *)((UINTPTR)*pcbArray + OS_PROCESS_INFO_LEN); + INT32 *user = (INT32 *)((UINTPTR)group + OS_PROCESS_GROUP_INFO_LEN); + SchedParam *param = (SchedParam *)((UINTPTR)*tcbArray + OS_TASK_INFO_LEN); + *schedParam = param; for (UINT32 tid = 0; tid < g_taskMaxNum; tid++) { const LosTaskCB *taskCB = *tcbArray + tid; @@ -268,6 +264,7 @@ STATIC VOID ProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, LosTaskCB **t if (!OsProcessIsDead(processCB) && !OsProcessIsInit(processCB)) { processCB->processStatus |= (taskCB->taskStatus & OS_TASK_STATUS_MASK); } + taskCB->ops->schedParamGet(taskCB, ¶m[tid]); } for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) { @@ -277,9 +274,9 @@ STATIC VOID ProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, LosTaskCB **t } if (processCB->group != NULL) { - (*group)[processCB->processID] = processCB->group->groupID; + group[processCB->processID] = processCB->group->groupID; } else { - (*group)[processCB->processID] = -1; + group[processCB->processID] = -1; } #ifdef LOSCFG_SECURITY_CAPABILITY @@ -294,22 +291,23 @@ STATIC VOID ProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, LosTaskCB **t } } -STATIC VOID ProcessInfoShow(const LosProcessCB *pcbArray, const INT32 *group, - const UINT32 *memArray, VOID *seqBuf, UINT16 flag) +STATIC VOID ProcessInfoShow(const LosProcessCB *pcbArray, const SchedParam *param, + UINTPTR cpupInfo, VOID *seqBuf, UINT16 flag) { #ifdef LOSCFG_KERNEL_CPUP + const CPUP_INFO_S *cpupAll = NULL; + const CPUP_INFO_S *cpup10s = NULL; + const CPUP_INFO_S *cpup1s = NULL; + ProcessCpupInfoBaseGet(cpupInfo, &cpupAll, &cpup10s, &cpup1s); UINT32 pid = OsGetIdleProcessID(); - UINT32 sysUsage = LOS_CPUP_PRECISION - processCpupAll[pid].usage; + UINT32 sysUsage = LOS_CPUP_PRECISION - cpupAll[pid].usage; - PROCESS_INFO_SHOW(seqBuf, "\n allCpu(%%): %4u.%02u sys, %4u.%02u idle\n", - sysUsage / LOS_CPUP_PRECISION_MULT, - sysUsage % LOS_CPUP_PRECISION_MULT, - processCpupAll[pid].usage / LOS_CPUP_PRECISION_MULT, - processCpupAll[pid].usage % LOS_CPUP_PRECISION_MULT); + SHOW("\n allCpu(%%): %4u.%02u sys, %4u.%02u idle\n", sysUsage / CPUP_MULT, sysUsage % CPUP_MULT, + cpupAll[pid].usage / CPUP_MULT, cpupAll[pid].usage % CPUP_MULT); #endif ProcessInfoTitle(seqBuf, flag); - AllProcessDataShow(pcbArray, group, memArray, seqBuf, flag); + AllProcessDataShow(pcbArray, param, cpupInfo, seqBuf, flag); } STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus) @@ -320,6 +318,8 @@ STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus) return (UINT8 *)"Running"; } else if (taskStatus & OS_TASK_STATUS_READY) { return (UINT8 *)"Ready"; + } else if (taskStatus & OS_TASK_STATUS_FROZEN) { + return (UINT8 *)"Frozen"; } else if (taskStatus & OS_TASK_STATUS_SUSPENDED) { return (UINT8 *)"Suspended"; } else if (taskStatus & OS_TASK_STATUS_DELAY) { @@ -340,7 +340,7 @@ STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus) STATIC VOID TaskWaterLineGet(UINTPTR waterLineBase, LosTaskCB *tcbArray) { UINT32 intSave; - taskWaterLine = (UINT32 *)waterLineBase; + UINT32 *taskWaterLine = (UINT32 *)waterLineBase; for (UINT32 tid = 0; tid < g_taskMaxNum; ++tid) { const LosTaskCB *taskCB = g_taskCBArray + tid; @@ -428,96 +428,108 @@ EXIT: STATIC VOID TaskInfoTitle(VOID *seqBuf, UINT16 flag) { - PROCESS_INFO_SHOW(seqBuf, "\r\n TID PID"); + SHOW("\r\n TID PID"); #ifdef LOSCFG_KERNEL_SMP - PROCESS_INFO_SHOW(seqBuf, " Affi CPU"); + SHOW(" Affi CPU"); #endif - PROCESS_INFO_SHOW(seqBuf, " Status Policy Priority StackSize WaterLine"); + SHOW(" Status Policy Priority StackSize WaterLine"); if (flag & OS_PROCESS_INFO_ALL) { #ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, " CPUUSE CPUUSE10s CPUUSE1s"); + SHOW(" CPUUSE CPUUSE10s CPUUSE1s"); #endif /* LOSCFG_KERNEL_CPUP */ #ifdef LOSCFG_SHELL_CMD_DEBUG - PROCESS_INFO_SHOW(seqBuf, " StackPoint TopOfStack PendReason LockID"); + SHOW(" StackPoint TopOfStack PendReason LockID"); #endif } else { #ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, " CPUUSE10s "); + SHOW(" CPUUSE10s "); #endif /* LOSCFG_KERNEL_CPUP */ } - PROCESS_INFO_SHOW(seqBuf, " TaskName\n"); + SHOW(" TaskName\n"); } -STATIC INLINE VOID TaskDataShow(const LosTaskCB *taskCB, VOID *seqBuf, UINT16 flag) +STATIC VOID AllTaskInfoDataShow(const LosTaskCB *allTaskArray, UINTPTR cpupInfo, VOID *seqBuf, UINT16 flag) { + const SchedParam *param = (const SchedParam *)((UINTPTR)allTaskArray + OS_TASK_INFO_LEN); + const UINT32 *waterLine = (const UINT32 *)((UINTPTR)allTaskArray + OS_TASK_INFO_LEN + OS_TASK_SCHED_INFO_LEN); +#ifdef LOSCFG_KERNEL_CPUP + const CPUP_INFO_S *cpupAll = NULL; + const CPUP_INFO_S *cpup10s = NULL; + const CPUP_INFO_S *cpup1s = NULL; + TaskCpupInfoBaseGet(cpupInfo, &cpupAll, &cpup10s, &cpup1s); +#else + (VOID)cpupInfo; +#endif + for (UINT32 pid = 1; pid < g_processMaxNum; ++pid) { + for (UINT32 tid = 0; tid < g_taskMaxNum; ++tid) { + const LosTaskCB *taskCB = allTaskArray + tid; + if (OsTaskIsUnused(taskCB) || (taskCB->processID != pid)) { + continue; + } #ifdef LOSCFG_SHELL_CMD_DEBUG - UINTPTR lockID = 0; - CHAR pendReason[OS_PEND_REASON_MAX_LEN] = { 0 }; + UINTPTR lockID = 0; + CHAR pendReason[OS_PEND_REASON_MAX_LEN] = { 0 }; #endif - PROCESS_INFO_SHOW(seqBuf, " %4u%5u", taskCB->taskID, taskCB->processID); + SHOW(" %4u%5u", tid, taskCB->processID); #ifdef LOSCFG_KERNEL_SMP - PROCESS_INFO_SHOW(seqBuf, "%#5x%4d ", taskCB->cpuAffiMask, (INT16)(taskCB->currCpu)); + SHOW("%#5x%4d ", taskCB->cpuAffiMask, (INT16)(taskCB->currCpu)); #endif - - PROCESS_INFO_SHOW(seqBuf, "%9s%7s%9u%#10x%#10x", ConvertTaskStatusToString(taskCB->taskStatus), - ConvertSchedPolicyToString(taskCB->policy), taskCB->priority, - taskCB->stackSize, taskWaterLine[taskCB->taskID]); - if (flag & OS_PROCESS_INFO_ALL) { + SHOW("%9s%7s%9u%#10x%#10x", ConvertTaskStatusToString(taskCB->taskStatus), + ConvertSchedPolicyToString(param[tid].policy), param[tid].priority, taskCB->stackSize, waterLine[tid]); + if (flag & OS_PROCESS_INFO_ALL) { #ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, "%4u.%-2u%7u.%-2u%6u.%-2u ", - taskCpupAll[taskCB->taskID].usage / LOS_CPUP_PRECISION_MULT, - taskCpupAll[taskCB->taskID].usage % LOS_CPUP_PRECISION_MULT, - taskCpup10s[taskCB->taskID].usage / LOS_CPUP_PRECISION_MULT, - taskCpup10s[taskCB->taskID].usage % LOS_CPUP_PRECISION_MULT, - taskCpup1s[taskCB->taskID].usage / LOS_CPUP_PRECISION_MULT, - taskCpup1s[taskCB->taskID].usage % LOS_CPUP_PRECISION_MULT); + SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ", cpupAll[tid].usage / CPUP_MULT, cpupAll[tid].usage % CPUP_MULT, + cpup10s[tid].usage / CPUP_MULT, cpup10s[tid].usage % CPUP_MULT, + cpup1s[tid].usage / CPUP_MULT, cpup1s[tid].usage % CPUP_MULT); #endif /* LOSCFG_KERNEL_CPUP */ #ifdef LOSCFG_SHELL_CMD_DEBUG - TaskPendingReasonInfoGet(taskCB, pendReason, OS_PEND_REASON_MAX_LEN, &lockID); - PROCESS_INFO_SHOW(seqBuf, "%#12x%#12x%11s%#11x", taskCB->stackPointer, taskCB->topOfStack, pendReason, lockID); + TaskPendingReasonInfoGet(taskCB, pendReason, OS_PEND_REASON_MAX_LEN, &lockID); + SHOW("%#12x%#12x%11s%#11x", taskCB->stackPointer, taskCB->topOfStack, pendReason, lockID); #endif - } else { + } else { #ifdef LOSCFG_KERNEL_CPUP - PROCESS_INFO_SHOW(seqBuf, "%8u.%-2u ", - taskCpup10s[taskCB->taskID].usage / LOS_CPUP_PRECISION_MULT, - taskCpup10s[taskCB->taskID].usage % LOS_CPUP_PRECISION_MULT); + SHOW("%8u.%-2u ", cpup10s[tid].usage / CPUP_MULT, cpup10s[tid].usage % CPUP_MULT); #endif /* LOSCFG_KERNEL_CPUP */ - } - PROCESS_INFO_SHOW(seqBuf, " %-32s\n", taskCB->taskName); -} - -STATIC VOID AllTaskInfoDataShow(const LosTaskCB *allTaskArray, VOID *seqBuf, UINT16 flag) -{ - for (UINT32 pid = 1; pid < g_processMaxNum; ++pid) { - for (UINT32 tid = 0; tid < g_taskMaxNum; ++tid) { - const LosTaskCB *taskCB = allTaskArray + tid; - if (OsTaskIsUnused(taskCB) || (taskCB->processID != pid)) { - continue; } - - TaskDataShow(taskCB, seqBuf, flag); + SHOW(" %-32s\n", taskCB->taskName); } } } -STATIC VOID TaskInfoData(const LosTaskCB *allTaskArray, VOID *seqBuf, UINT16 flag) +STATIC VOID TaskInfoData(const LosTaskCB *allTaskArray, UINTPTR cpupInfo, VOID *seqBuf, UINT16 flag) { TaskInfoTitle(seqBuf, flag); - AllTaskInfoDataShow(allTaskArray, seqBuf, flag); + AllTaskInfoDataShow(allTaskArray, cpupInfo, seqBuf, flag); } #ifdef LOSCFG_KERNEL_CPUP +STATIC VOID TaskCpupInfoBaseGet(UINTPTR base, const CPUP_INFO_S **cpupAll, + const CPUP_INFO_S **cpup10s, const CPUP_INFO_S **cpup1s) +{ + UINTPTR processCpupAll = base + OS_PROCESS_UID_INFO_LEN; + *cpupAll = (CPUP_INFO_S *)(processCpupAll + OS_PROCESS_CPUP_LEN); + UINTPTR processCpup10s = processCpupAll + OS_PROCESS_AND_TASK_CPUP_LEN; + *cpup10s = (CPUP_INFO_S *)(processCpup10s + OS_PROCESS_CPUP_LEN); + UINTPTR processCpup1s = processCpup10s + OS_PROCESS_AND_TASK_CPUP_LEN; + *cpup1s = (CPUP_INFO_S *)(processCpup1s + OS_PROCESS_CPUP_LEN); +} + +STATIC VOID ProcessCpupInfoBaseGet(UINTPTR base, const CPUP_INFO_S **cpupAll, + const CPUP_INFO_S **cpup10s, const CPUP_INFO_S **cpup1s) +{ + *cpupAll = (CPUP_INFO_S *)(base + OS_PROCESS_UID_INFO_LEN); + *cpup10s = (CPUP_INFO_S *)((UINTPTR)*cpupAll + OS_PROCESS_AND_TASK_CPUP_LEN); + *cpup1s = (CPUP_INFO_S *)((UINTPTR)*cpup10s + OS_PROCESS_AND_TASK_CPUP_LEN); +} + STATIC VOID TaskCpupInfoGet(UINTPTR base) { UINT32 intSave; - processCpupAll = (CPUP_INFO_S *)(base + OS_PROCESS_UID_INFO_LEN); - taskCpupAll = (CPUP_INFO_S *)((UINTPTR)processCpupAll + OS_PROCESS_CPUP_LEN); - processCpup10s = (CPUP_INFO_S *)((UINTPTR)processCpupAll + OS_PROCESS_AND_TASK_CPUP_LEN); - taskCpup10s = (CPUP_INFO_S *)((UINTPTR)processCpup10s + OS_PROCESS_CPUP_LEN); - processCpup1s = (CPUP_INFO_S *)((UINTPTR)processCpup10s + OS_PROCESS_AND_TASK_CPUP_LEN); - taskCpup1s = (CPUP_INFO_S *)((UINTPTR)processCpup1s + OS_PROCESS_CPUP_LEN); + CPUP_INFO_S *processCpupAll = (CPUP_INFO_S *)(base + OS_PROCESS_UID_INFO_LEN); + CPUP_INFO_S *processCpup10s = (CPUP_INFO_S *)((UINTPTR)processCpupAll + OS_PROCESS_AND_TASK_CPUP_LEN); + CPUP_INFO_S *processCpup1s = (CPUP_INFO_S *)((UINTPTR)processCpup10s + OS_PROCESS_AND_TASK_CPUP_LEN); SCHEDULER_LOCK(intSave); (VOID)OsGetAllProcessAndTaskCpuUsageUnsafe(CPUP_ALL_TIME, processCpupAll, OS_PROCESS_AND_TASK_CPUP_LEN); @@ -534,10 +546,10 @@ STATIC VOID TaskCpupInfoGet(UINTPTR base) #endif /* - * | all pcb info | group | user info | task and process cpup info | process mem info | all tcb info | task water line | + * | pcb | group | user | task and process cpup | process mem | tcb | sched param | task water line | */ -STATIC VOID ProcessAndTaskInfoGet(LosProcessCB **pcbArray, INT32 **group, LosTaskCB **tcbArray, - UINT32 **memArray, UINT16 flag) +STATIC VOID ProcessAndTaskInfoGet(LosProcessCB **pcbArray, LosTaskCB **tcbArray, + SchedParam **schedParam, UINTPTR *cpupInfo, UINT16 flag) { UINT32 intSave; UINT32 processInfoLen = OS_PROCESS_ALL_INFO_LEN; @@ -553,30 +565,30 @@ STATIC VOID ProcessAndTaskInfoGet(LosProcessCB **pcbArray, INT32 **group, LosTas *tcbArray = (LosTaskCB *)((UINTPTR)*pcbArray + processInfoLen); (VOID)memcpy_s(*tcbArray, OS_TASK_INFO_LEN, g_taskCBArray, OS_TASK_INFO_LEN); - ProcessInfoGet(pcbArray, group, tcbArray); + ProcessInfoGet(pcbArray, tcbArray, schedParam); SCHEDULER_UNLOCK(intSave); #ifdef LOSCFG_KERNEL_CPUP - TaskCpupInfoGet((UINTPTR)*pcbArray + OS_PROCESS_INFO_LEN + OS_PROCESS_GROUP_INFO_LEN); + *cpupInfo = (UINTPTR)*pcbArray + OS_PROCESS_INFO_LEN + OS_PROCESS_GROUP_INFO_LEN; + TaskCpupInfoGet(*cpupInfo); #endif #ifdef LOSCFG_KERNEL_VM if (flag & OS_PROCESS_MEM_INFO) { - *memArray = (UINT32 *)((UINTPTR)*pcbArray + OS_PROCESS_ALL_INFO_LEN); - ProcessMemUsageGet(*memArray, *pcbArray); + ProcessMemUsageGet(*pcbArray); } #endif - TaskWaterLineGet((UINTPTR)*tcbArray + OS_TASK_INFO_LEN, *tcbArray); + TaskWaterLineGet((UINTPTR)*tcbArray + OS_TASK_INFO_LEN + OS_TASK_SCHED_INFO_LEN, *tcbArray); } LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqBuf, UINT16 flag) { UINT32 size; LosProcessCB *pcbArray = NULL; - INT32 *group = NULL; LosTaskCB *tcbArray = NULL; - UINT32 *memArray = NULL; + SchedParam *schedParam = NULL; + UINTPTR cpupInfo = 0; if (taskID == OS_ALL_TASK_MASK) { if (flag & OS_PROCESS_MEM_INFO) { @@ -590,9 +602,9 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqBuf, return LOS_NOK; } (VOID)memset_s(pcbArray, size, 0, size); - ProcessAndTaskInfoGet(&pcbArray, &group, &tcbArray, &memArray, flag); - ProcessInfoShow(pcbArray, group, memArray, seqBuf, flag); - TaskInfoData(tcbArray, seqBuf, flag); + ProcessAndTaskInfoGet(&pcbArray, &tcbArray, &schedParam, &cpupInfo, flag); + ProcessInfoShow(pcbArray, schedParam, cpupInfo, seqBuf, flag); + TaskInfoData(tcbArray, cpupInfo, seqBuf, flag); (VOID)LOS_MemFree(m_aucSysMem1, pcbArray); } diff --git a/kernel/base/mp/los_mp.c b/kernel/base/mp/los_mp.c index c4e9b183..67bc7012 100644 --- a/kernel/base/mp/los_mp.c +++ b/kernel/base/mp/los_mp.c @@ -62,7 +62,7 @@ VOID OsMpScheduleHandler(VOID) * set schedule flag to differ from wake function, * so that the scheduler can be triggered at the end of irq. */ - OsSchedRunQuePendingSet(); + OsSchedRunqueuePendingSet(); } VOID OsMpHaltHandler(VOID) diff --git a/kernel/base/sched/los_idle.c b/kernel/base/sched/los_idle.c new file mode 100644 index 00000000..d0b3b0ed --- /dev/null +++ b/kernel/base/sched/los_idle.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sched_pri.h" +#include "los_process_pri.h" + +STATIC VOID IdleDequeue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC VOID IdleEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC UINT32 IdleWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks); +STATIC VOID IdleWake(LosTaskCB *resumedTask); +STATIC UINT32 IdleSchedParamGet(const LosTaskCB *taskCB, SchedParam *param); +STATIC VOID IdleYield(LosTaskCB *runTask); +STATIC VOID IdleStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC UINT32 IdleResume(LosTaskCB *taskCB, BOOL *needSched); +STATIC UINT64 IdleTimeSliceGet(const LosTaskCB *taskCB); +STATIC VOID IdleTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); +STATIC INT32 IdleParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); +STATIC VOID IdlePriorityInheritance(LosTaskCB *owner, const SchedParam *param); +STATIC VOID IdlePriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); + +const STATIC SchedOps g_idleOps = { + .dequeue = IdleDequeue, + .enqueue = IdleEnqueue, + .wait = IdleWait, + .wake = IdleWake, + .schedParamModify = NULL, + .schedParamGet = IdleSchedParamGet, + .delay = NULL, + .yield = IdleYield, + .start = IdleStartToRun, + .exit = NULL, + .suspend = NULL, + .resume = IdleResume, + .deadlineGet = IdleTimeSliceGet, + .timeSliceUpdate = IdleTimeSliceUpdate, + .schedParamCompare = IdleParamCompare, + .priorityInheritance = IdlePriorityInheritance, + .priorityRestore = IdlePriorityRestore, +}; + +STATIC VOID IdleTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime) +{ + (VOID)rq; + + taskCB->startTime = currTime; +} + +STATIC UINT64 IdleTimeSliceGet(const LosTaskCB *taskCB) +{ + (VOID)taskCB; + return (OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION); +} + +STATIC VOID IdleEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + (VOID)rq; + + taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; + taskCB->taskStatus |= OS_TASK_STATUS_READY; +} + +STATIC VOID IdleDequeue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + (VOID)rq; + + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; +} + +STATIC VOID IdleStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + IdleDequeue(rq, taskCB); +} + +STATIC VOID IdleYield(LosTaskCB *runTask) +{ + (VOID)runTask; + return; +} + +STATIC UINT32 IdleWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks) +{ + (VOID)runTask; + (VOID)list; + (VOID)ticks; + + return LOS_NOK; +} + +STATIC VOID IdleWake(LosTaskCB *resumedTask) +{ + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; + + if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { + OsSchedTimeoutQueueDelete(resumedTask); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + } + + if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_DEBUG + resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; + resumedTask->schedStat.pendCount++; +#endif + resumedTask->ops->enqueue(OsSchedRunqueue(), resumedTask); + } +} + +STATIC UINT32 IdleResume(LosTaskCB *taskCB, BOOL *needSched) +{ + *needSched = FALSE; + + taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; + if (!OsTaskIsBlocked(taskCB)) { + taskCB->ops->enqueue(OsSchedRunqueue(), taskCB); + *needSched = TRUE; + } + return LOS_OK; +} + +STATIC UINT32 IdleSchedParamGet(const LosTaskCB *taskCB, SchedParam *param) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + param->policy = sched->policy; + param->basePrio = sched->basePrio; + param->priority = sched->priority; + param->timeSlice = 0; + return LOS_OK; +} + +STATIC INT32 IdleParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2) +{ + return 0; +} + +STATIC VOID IdlePriorityInheritance(LosTaskCB *owner, const SchedParam *param) +{ + (VOID)owner; + (VOID)param; + return; +} + +STATIC VOID IdlePriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param) +{ + (VOID)owner; + (VOID)list; + (VOID)param; + return; +} + +VOID IdleTaskSchedParamInit(LosTaskCB *taskCB) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + sched->policy = LOS_SCHED_IDLE; + sched->basePrio = OS_PROCESS_PRIORITY_LOWEST; + sched->priority = OS_TASK_PRIORITY_LOWEST; + sched->initTimeSlice = 0; + taskCB->timeSlice = sched->initTimeSlice; + taskCB->taskStatus = OS_TASK_STATUS_SUSPENDED; + taskCB->ops = &g_idleOps; +} diff --git a/kernel/base/sched/los_priority.c b/kernel/base/sched/los_priority.c new file mode 100644 index 00000000..628a46f6 --- /dev/null +++ b/kernel/base/sched/los_priority.c @@ -0,0 +1,546 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_sched_pri.h" +#include "los_task_pri.h" +#include "los_process_pri.h" +#include "los_hook.h" +#include "los_tick_pri.h" +#include "los_mp.h" + +#define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF +#define PRIQUEUE_PRIOR0_BIT 0x80000000U +#define OS_SCHED_TIME_SLICES_MIN ((5000 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 5ms */ +#define OS_SCHED_TIME_SLICES_MAX ((LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) +#define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN) +#define OS_SCHED_READY_MAX 30 +#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */ + +STATIC HPFRunqueue g_schedHPF; + +STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks); +STATIC VOID HPFWake(LosTaskCB *resumedTask); +STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param); +STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param); +STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime); +STATIC VOID HPFYield(LosTaskCB *runTask); +STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB); +STATIC VOID HPFExit(LosTaskCB *taskCB); +STATIC UINT32 HPFSuspend(LosTaskCB *taskCB); +STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched); +STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB); +STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime); +STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2); +STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param); +STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param); + +const STATIC SchedOps g_priorityOps = { + .dequeue = HPFDequeue, + .enqueue = HPFEnqueue, + .wait = HPFWait, + .wake = HPFWake, + .schedParamModify = HPFSchedParamModify, + .schedParamGet = HPFSchedParamGet, + .delay = HPFDelay, + .yield = HPFYield, + .start = HPFStartToRun, + .exit = HPFExit, + .suspend = HPFSuspend, + .resume = HPFResume, + .deadlineGet = HPFTimeSliceGet, + .timeSliceUpdate = HPFTimeSliceUpdate, + .schedParamCompare = HPFParamCompare, + .priorityInheritance = HPFPriorityInheritance, + .priorityRestore = HPFPriorityRestore, +}; + +STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + LOS_ASSERT(currTime >= taskCB->startTime); + + INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime); + + LOS_ASSERT(incTime >= 0); + + if (sched->policy == LOS_SCHED_RR) { + taskCB->timeSlice -= incTime; +#ifdef LOSCFG_SCHED_DEBUG + taskCB->schedStat.timeSliceRealTime += incTime; +#endif + } + taskCB->irqUsedTime = 0; + taskCB->startTime = currTime; + if (taskCB->timeSlice <= OS_TIME_SLICE_MIN) { + rq->schedFlag |= INT_PEND_RESCH; + } + +#ifdef LOSCFG_SCHED_DEBUG + taskCB->schedStat.allRuntime += incTime; +#endif +} + +STATIC UINT64 HPFTimeSliceGet(const LosTaskCB *taskCB) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + INT32 timeSlice = taskCB->timeSlice; + + timeSlice = (timeSlice <= OS_TIME_SLICE_MIN) ? sched->initTimeSlice : timeSlice; + return (taskCB->startTime + timeSlice); +} + +STATIC INLINE UINT32 TimeSliceCalculate(HPFRunqueue *rq, UINT16 basePrio, UINT16 priority) +{ + UINT32 time; + UINT32 readyTasks; + + HPFQueue *queueList = &rq->queueList[basePrio]; + readyTasks = queueList->readyTasks[priority]; + if (readyTasks > OS_SCHED_READY_MAX) { + return OS_SCHED_TIME_SLICES_MIN; + } + time = ((OS_SCHED_READY_MAX - readyTasks) * OS_SCHED_TIME_SLICES_DIFF) / OS_SCHED_READY_MAX; + return (time + OS_SCHED_TIME_SLICES_MIN); +} + +STATIC INLINE VOID PriQueHeadInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority) +{ + HPFQueue *queueList = &rq->queueList[basePrio]; + LOS_DL_LIST *priQueList = &queueList->priQueList[0]; + UINT32 *bitmap = &queueList->queueBitmap; + + /* + * Task control blocks are inited as zero. And when task is deleted, + * and at the same time would be deleted from priority queue or + * other lists, task pend node will restored as zero. + */ + LOS_ASSERT(priQue->pstNext == NULL); + + if (*bitmap == 0) { + rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio; + } + + if (LOS_ListEmpty(&priQueList[priority])) { + *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority; + } + + LOS_ListHeadInsert(&priQueList[priority], priQue); + queueList->readyTasks[priority]++; +} + +STATIC INLINE VOID PriQueTailInsert(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority) +{ + HPFQueue *queueList = &rq->queueList[basePrio]; + LOS_DL_LIST *priQueList = &queueList->priQueList[0]; + UINT32 *bitmap = &queueList->queueBitmap; + + /* + * Task control blocks are inited as zero. And when task is deleted, + * and at the same time would be deleted from priority queue or + * other lists, task pend node will restored as zero. + */ + LOS_ASSERT(priQue->pstNext == NULL); + + if (*bitmap == 0) { + rq->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> basePrio; + } + + if (LOS_ListEmpty(&priQueList[priority])) { + *bitmap |= PRIQUEUE_PRIOR0_BIT >> priority; + } + + LOS_ListTailInsert(&priQueList[priority], priQue); + queueList->readyTasks[priority]++; +} + +STATIC INLINE VOID PriQueDelete(HPFRunqueue *rq, UINT32 basePrio, LOS_DL_LIST *priQue, UINT32 priority) +{ + HPFQueue *queueList = &rq->queueList[basePrio]; + LOS_DL_LIST *priQueList = &queueList->priQueList[0]; + UINT32 *bitmap = &queueList->queueBitmap; + + LOS_ListDelete(priQue); + queueList->readyTasks[priority]--; + if (LOS_ListEmpty(&priQueList[priority])) { + *bitmap &= ~(PRIQUEUE_PRIOR0_BIT >> priority); + } + + if (*bitmap == 0) { + rq->queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> basePrio); + } +} + +STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB) +{ + LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + switch (sched->policy) { + case LOS_SCHED_RR: { + if (taskCB->timeSlice > OS_TIME_SLICE_MIN) { + PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); + } else { + sched->initTimeSlice = TimeSliceCalculate(rq, sched->basePrio, sched->priority); + taskCB->timeSlice = sched->initTimeSlice; + PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); +#ifdef LOSCFG_SCHED_DEBUG + taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime; + taskCB->schedStat.timeSliceCount++; +#endif + } + break; + } + case LOS_SCHED_FIFO: { + /* The time slice of FIFO is always greater than 0 unless the yield is called */ + if ((taskCB->timeSlice > OS_TIME_SLICE_MIN) && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + PriQueHeadInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); + } else { + sched->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; + taskCB->timeSlice = sched->initTimeSlice; + PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority); + } + break; + } + default: + LOS_ASSERT(0); + break; + } + + taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; + taskCB->taskStatus |= OS_TASK_STATUS_READY; +} + +STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ +#ifdef LOSCFG_SCHED_DEBUG + if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + taskCB->startTime = OsGetCurrSchedTimeCycle(); + } +#endif + PriQueInsert(rq->hpfRunqueue, taskCB); +} + +STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + PriQueDelete(rq->hpfRunqueue, sched->basePrio, &taskCB->pendList, sched->priority); + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; + } +} + +STATIC VOID HPFStartToRun(SchedRunqueue *rq, LosTaskCB *taskCB) +{ + HPFDequeue(rq, taskCB); +} + +STATIC VOID HPFExit(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + HPFDequeue(OsSchedRunqueue(), taskCB); + } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { + LOS_ListDelete(&taskCB->pendList); + taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; + } + + if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { + OsSchedTimeoutQueueDelete(taskCB); + taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); + } +} + +STATIC VOID HPFYield(LosTaskCB *runTask) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + runTask->timeSlice = 0; + + runTask->startTime = OsGetCurrSchedTimeCycle(); + HPFEnqueue(rq, runTask); + OsSchedResched(); +} + +STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime) +{ + runTask->taskStatus |= OS_TASK_STATUS_DELAY; + runTask->waitTime = waitTime; + + OsSchedResched(); + return LOS_OK; +} + +STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks) +{ + runTask->taskStatus |= OS_TASK_STATUS_PENDING; + LOS_ListTailInsert(list, &runTask->pendList); + + if (ticks != LOS_WAIT_FOREVER) { + runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME; + runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks); + } + + if (OsPreemptableInSched()) { + OsSchedResched(); + if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + return LOS_ERRNO_TSK_TIMEOUT; + } + } + + return LOS_OK; +} + +STATIC VOID HPFWake(LosTaskCB *resumedTask) +{ + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; + + if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { + OsSchedTimeoutQueueDelete(resumedTask); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + } + + if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_DEBUG + resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; + resumedTask->schedStat.pendCount++; +#endif + HPFEnqueue(OsSchedRunqueue(), resumedTask); + } +} + +STATIC BOOL BasePriorityModify(SchedRunqueue *rq, LosTaskCB *taskCB, UINT16 priority) +{ + LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); + BOOL needSched = FALSE; + + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + taskCB->ops->dequeue(rq, taskCB); + sched->basePrio = priority; + taskCB->ops->enqueue(rq, taskCB); + } else { + sched->basePrio = priority; + } + if (taskCB->taskStatus & (OS_TASK_STATUS_READY | OS_TASK_STATUS_RUNNING)) { + needSched = TRUE; + } + } + + return needSched; +} + +STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param) +{ + SchedRunqueue *rq = OsSchedRunqueue(); + BOOL needSched = FALSE; + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + if (sched->policy != param->policy) { + sched->policy = param->policy; + taskCB->timeSlice = 0; + } + + if (sched->basePrio != param->basePrio) { + needSched = BasePriorityModify(rq, taskCB, param->basePrio); + } + + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + HPFDequeue(rq, taskCB); + sched->priority = param->priority; + HPFEnqueue(rq, taskCB); + return TRUE; + } + + sched->priority = param->priority; + OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, sched->priority); + if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { + HPFEnqueue(rq, taskCB); + return TRUE; + } + + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + return TRUE; + } + + return needSched; +} + +STATIC UINT32 HPFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + param->policy = sched->policy; + param->basePrio = sched->basePrio; + param->priority = sched->priority; + param->timeSlice = sched->initTimeSlice; + return LOS_OK; +} + +STATIC UINT32 HPFSuspend(LosTaskCB *taskCB) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + HPFDequeue(OsSchedRunqueue(), taskCB); + } + + SchedTaskFreeze(taskCB); + + taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED; + OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB); + if (taskCB == OsCurrTaskGet()) { + OsSchedResched(); + } + return LOS_OK; +} + +STATIC UINT32 HPFResume(LosTaskCB *taskCB, BOOL *needSched) +{ + *needSched = FALSE; + + SchedTaskUnfreeze(taskCB); + + taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; + if (!OsTaskIsBlocked(taskCB)) { + HPFEnqueue(OsSchedRunqueue(), taskCB); + *needSched = TRUE; + } + + return LOS_OK; +} + +STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2) +{ + SchedHPF *param1 = (SchedHPF *)sp1; + SchedHPF *param2 = (SchedHPF *)sp2; + + if (param1->basePrio != param2->basePrio) { + return (param1->basePrio - param2->basePrio); + } + + return (param1->priority - param2->priority); +} + +STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param) +{ + SchedHPF *sp = (SchedHPF *)&owner->sp; + + if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) { + return; + } + + if (sp->priority <= param->priority) { + return; + } + + LOS_BitmapSet(&sp->priBitmap, sp->priority); + sp->priority = param->priority; +} + +STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param) +{ + UINT16 priority; + LosTaskCB *pendedTask = NULL; + + if ((param->policy != LOS_SCHED_RR) && (param->policy != LOS_SCHED_FIFO)) { + return; + } + + SchedHPF *sp = (SchedHPF *)&owner->sp; + if (sp->priority < param->priority) { + if (LOS_HighBitGet(sp->priBitmap) != param->priority) { + LOS_BitmapClr(&sp->priBitmap, param->priority); + } + return; + } + + if (sp->priBitmap == 0) { + return; + } + + if ((list != NULL) && !LOS_ListEmpty((LOS_DL_LIST *)list)) { + priority = LOS_HighBitGet(sp->priBitmap); + LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) { + SchedHPF *pendSp = (SchedHPF *)&pendedTask->sp; + if ((pendedTask->ops == owner->ops) && (priority != pendSp->priority)) { + LOS_BitmapClr(&sp->priBitmap, pendSp->priority); + } + } + } + + priority = LOS_LowBitGet(sp->priBitmap); + if (priority != LOS_INVALID_BIT_INDEX) { + LOS_BitmapClr(&sp->priBitmap, priority); + sp->priority = priority; + } +} + +VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy, + const SchedParam *parentParam, + const TSK_INIT_PARAM_S *param) +{ + SchedHPF *sched = (SchedHPF *)&taskCB->sp; + + sched->policy = policy; + if (param != NULL) { + sched->priority = param->usTaskPrio; + } else { + sched->priority = parentParam->priority; + } + sched->basePrio = parentParam->basePrio; + + sched->initTimeSlice = 0; + taskCB->timeSlice = sched->initTimeSlice; + taskCB->ops = &g_priorityOps; +} + +VOID HPFProcessDefaultSchedParamGet(SchedParam *param) +{ + param->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST; +} + +VOID HPFSchedPolicyInit(SchedRunqueue *rq) +{ + if (ArchCurrCpuid() > 0) { + rq->hpfRunqueue = &g_schedHPF; + return; + } + + for (UINT16 index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) { + HPFQueue *queueList = &g_schedHPF.queueList[index]; + LOS_DL_LIST *priQue = &queueList->priQueList[0]; + for (UINT16 prio = 0; prio < OS_PRIORITY_QUEUE_NUM; prio++) { + LOS_ListInit(&priQue[prio]); + } + } + + rq->hpfRunqueue = &g_schedHPF; +} diff --git a/kernel/base/sched/los_sched.c b/kernel/base/sched/los_sched.c index 597a29f0..a6742717 100644 --- a/kernel/base/sched/los_sched.c +++ b/kernel/base/sched/los_sched.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -45,65 +45,15 @@ #include "los_stackinfo_pri.h" #endif #include "los_mp.h" -#ifdef LOSCFG_SCHED_DEBUG -#include "los_statistics_pri.h" -#endif -#include "los_pm_pri.h" - -#define OS_32BIT_MAX 0xFFFFFFFFUL -#define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF -#define OS_PRIORITY_QUEUE_NUM 32 -#define PRIQUEUE_PRIOR0_BIT 0x80000000U -#define OS_SCHED_TIME_SLICES_MIN ((5000 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 5ms */ -#define OS_SCHED_TIME_SLICES_MAX ((LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) -#define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN) -#define OS_SCHED_READY_MAX 30 -#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */ -#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ - OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) - -typedef struct { - LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM]; - UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM]; - UINT32 queueBitmap; -} SchedQueue; - -typedef struct { - SchedQueue queueList[OS_PRIORITY_QUEUE_NUM]; - UINT32 queueBitmap; -} Sched; - -SchedRunQue g_schedRunQue[LOSCFG_KERNEL_CORE_NUM]; -STATIC Sched g_sched; - -STATIC INLINE VOID TimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) -{ - LOS_ASSERT(currTime >= taskCB->startTime); - - INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime); - LOS_ASSERT(incTime >= 0); - - if (taskCB->policy == LOS_SCHED_RR) { - taskCB->timeSlice -= incTime; -#ifdef LOSCFG_SCHED_DEBUG - taskCB->schedStat.timeSliceRealTime += incTime; -#endif - } - taskCB->irqUsedTime = 0; - taskCB->startTime = currTime; +SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM]; -#ifdef LOSCFG_SCHED_DEBUG - taskCB->schedStat.allRuntime += incTime; -#endif -} - -STATIC INLINE VOID SchedSetNextExpireTime(UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) +STATIC INLINE VOID SchedNextExpireTimeSet(UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) { - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); BOOL isTimeSlice = FALSE; UINT64 currTime = OsGetCurrSchedTimeCycle(); - UINT64 nextExpireTime = OsGetSortLinkNextExpireTime(&rq->taskSortLink, currTime, OS_TICK_RESPONSE_PRECISION); + UINT64 nextExpireTime = OsGetSortLinkNextExpireTime(&rq->timeoutQueue, currTime, OS_TICK_RESPONSE_PRECISION); rq->schedFlag &= ~INT_PEND_TICK; if (rq->responseID == oldResponseID) { @@ -135,372 +85,22 @@ STATIC INLINE VOID SchedSetNextExpireTime(UINT32 responseID, UINT64 taskEndTime, rq->responseTime = currTime + HalClockTickTimerReload(nextResponseTime); } -VOID OsSchedUpdateExpireTime(VOID) +VOID OsSchedExpireTimeUpdate(VOID) { - UINT64 endTime; - LosTaskCB *runTask = OsCurrTaskGet(); - + UINT32 intSave; if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) { - OsSchedRunQuePendingSet(); + OsSchedRunqueuePendingSet(); return; } - if (runTask->policy == LOS_SCHED_RR) { - LOS_SpinLock(&g_taskSpin); - INT32 timeSlice = (runTask->timeSlice <= OS_TIME_SLICE_MIN) ? runTask->initTimeSlice : runTask->timeSlice; - endTime = runTask->startTime + timeSlice; - LOS_SpinUnlock(&g_taskSpin); - } else { - endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; - } - - SchedSetNextExpireTime(runTask->taskID, endTime, runTask->taskID); -} - -STATIC INLINE UINT32 SchedCalculateTimeSlice(UINT16 proPriority, UINT16 priority) -{ - UINT32 retTime; - UINT32 readyTasks; - - SchedQueue *queueList = &g_sched.queueList[proPriority]; - readyTasks = queueList->readyTasks[priority]; - if (readyTasks > OS_SCHED_READY_MAX) { - return OS_SCHED_TIME_SLICES_MIN; - } - retTime = ((OS_SCHED_READY_MAX - readyTasks) * OS_SCHED_TIME_SLICES_DIFF) / OS_SCHED_READY_MAX; - return (retTime + OS_SCHED_TIME_SLICES_MIN); -} - -STATIC INLINE VOID SchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) -{ - SchedQueue *queueList = &g_sched.queueList[proPriority]; - LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; - UINT32 *bitMap = &queueList->queueBitmap; - - /* - * Task control blocks are inited as zero. And when task is deleted, - * and at the same time would be deleted from priority queue or - * other lists, task pend node will restored as zero. - */ - LOS_ASSERT(priqueueItem->pstNext == NULL); - - if (*bitMap == 0) { - g_sched.queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; - } - - if (LOS_ListEmpty(&priQueueList[priority])) { - *bitMap |= PRIQUEUE_PRIOR0_BIT >> priority; - } - - LOS_ListHeadInsert(&priQueueList[priority], priqueueItem); - queueList->readyTasks[priority]++; -} - -STATIC INLINE VOID SchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) -{ - SchedQueue *queueList = &g_sched.queueList[proPriority]; - LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; - UINT32 *bitMap = &queueList->queueBitmap; - - /* - * Task control blocks are inited as zero. And when task is deleted, - * and at the same time would be deleted from priority queue or - * other lists, task pend node will restored as zero. - */ - LOS_ASSERT(priqueueItem->pstNext == NULL); - - if (*bitMap == 0) { - g_sched.queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; - } - - if (LOS_ListEmpty(&priQueueList[priority])) { - *bitMap |= PRIQUEUE_PRIOR0_BIT >> priority; - } - - LOS_ListTailInsert(&priQueueList[priority], priqueueItem); - queueList->readyTasks[priority]++; -} - -STATIC INLINE VOID SchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) -{ - SchedQueue *queueList = &g_sched.queueList[proPriority]; - LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; - UINT32 *bitMap = &queueList->queueBitmap; - - LOS_ListDelete(priqueueItem); - queueList->readyTasks[priority]--; - if (LOS_ListEmpty(&priQueueList[priority])) { - *bitMap &= ~(PRIQUEUE_PRIOR0_BIT >> priority); - } - - if (*bitMap == 0) { - g_sched.queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> proPriority); - } -} - -STATIC INLINE VOID SchedEnTaskQueue(LosTaskCB *taskCB) -{ - LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); - - switch (taskCB->policy) { - case LOS_SCHED_RR: { - if (taskCB->timeSlice > OS_TIME_SLICE_MIN) { - SchedPriQueueEnHead(taskCB->basePrio, &taskCB->pendList, taskCB->priority); - } else { - taskCB->initTimeSlice = SchedCalculateTimeSlice(taskCB->basePrio, taskCB->priority); - taskCB->timeSlice = taskCB->initTimeSlice; - SchedPriQueueEnTail(taskCB->basePrio, &taskCB->pendList, taskCB->priority); -#ifdef LOSCFG_SCHED_DEBUG - taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime; - taskCB->schedStat.timeSliceCount++; -#endif - } - break; - } - case LOS_SCHED_FIFO: { - /* The time slice of FIFO is always greater than 0 unless the yield is called */ - if ((taskCB->timeSlice > OS_TIME_SLICE_MIN) && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - SchedPriQueueEnHead(taskCB->basePrio, &taskCB->pendList, taskCB->priority); - } else { - taskCB->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; - taskCB->timeSlice = taskCB->initTimeSlice; - SchedPriQueueEnTail(taskCB->basePrio, &taskCB->pendList, taskCB->priority); - } - break; - } - case LOS_SCHED_IDLE: -#ifdef LOSCFG_SCHED_DEBUG - taskCB->schedStat.timeSliceCount = 1; -#endif - break; - default: - LOS_ASSERT(0); - break; - } - - taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; - taskCB->taskStatus |= OS_TASK_STATUS_READY; -} - -VOID OsSchedTaskDeQueue(LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - if (taskCB->policy != LOS_SCHED_IDLE) { - SchedPriQueueDelete(taskCB->basePrio, &taskCB->pendList, taskCB->priority); - } - taskCB->taskStatus &= ~OS_TASK_STATUS_READY; - } -} - -VOID OsSchedTaskEnQueue(LosTaskCB *taskCB) -{ -#ifdef LOSCFG_SCHED_DEBUG - if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - taskCB->startTime = OsGetCurrSchedTimeCycle(); - } -#endif - SchedEnTaskQueue(taskCB); -} - -VOID OsSchedTaskExit(LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - OsSchedTaskDeQueue(taskCB); - } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { - LOS_ListDelete(&taskCB->pendList); - taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; - } - - if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { - OsSchedDeTaskFromTimeList(taskCB); - taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); - } -} - -VOID OsSchedYield(VOID) -{ LosTaskCB *runTask = OsCurrTaskGet(); - - runTask->timeSlice = 0; - - runTask->startTime = OsGetCurrSchedTimeCycle(); - OsSchedTaskEnQueue(runTask); - OsSchedResched(); -} - -VOID OsSchedDelay(LosTaskCB *runTask, UINT64 waitTime) -{ - runTask->taskStatus |= OS_TASK_STATUS_DELAY; - runTask->waitTime = waitTime; - - OsSchedResched(); -} - -UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 ticks, BOOL needSched) -{ - LosTaskCB *runTask = OsCurrTaskGet(); - - runTask->taskStatus |= OS_TASK_STATUS_PENDING; - LOS_ListTailInsert(list, &runTask->pendList); - - if (ticks != LOS_WAIT_FOREVER) { - runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME; - runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks); - } - - if (needSched == TRUE) { - OsSchedResched(); - if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { - runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; - return LOS_ERRNO_TSK_TIMEOUT; - } - } - - return LOS_OK; -} - -VOID OsSchedTaskWake(LosTaskCB *resumedTask) -{ - LOS_ListDelete(&resumedTask->pendList); - resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; - - if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { - OsSchedDeTaskFromTimeList(resumedTask); - resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; - } - - if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { -#ifdef LOSCFG_SCHED_DEBUG - resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; - resumedTask->schedStat.pendCount++; -#endif - OsSchedTaskEnQueue(resumedTask); - } -} - -BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priority) -{ - if (taskCB->policy != policy) { - taskCB->policy = policy; - taskCB->timeSlice = 0; - } - - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - OsSchedTaskDeQueue(taskCB); - taskCB->priority = priority; - OsSchedTaskEnQueue(taskCB); - return TRUE; - } - - taskCB->priority = priority; - OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, taskCB->priority); - if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { - OsSchedTaskEnQueue(taskCB); - return TRUE; - } - - if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { - return TRUE; - } - - return FALSE; -} - -BOOL OsSchedModifyProcessSchedParam(UINT32 pid, UINT16 policy, UINT16 priority) -{ - LosProcessCB *processCB = OS_PCB_FROM_PID(pid); - LosTaskCB *taskCB = NULL; - BOOL needSched = FALSE; - (VOID)policy; - - LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - SchedPriQueueDelete(taskCB->basePrio, &taskCB->pendList, taskCB->priority); - SchedPriQueueEnTail(priority, &taskCB->pendList, taskCB->priority); - needSched = TRUE; - } else if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { - needSched = TRUE; - } - taskCB->basePrio = priority; - } - - return needSched; -} - -STATIC VOID SchedFreezeTask(LosTaskCB *taskCB) -{ - UINT64 responseTime; - - if (!OsIsPmMode()) { - return; - } - - if (!(taskCB->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY))) { - return; - } - - responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); - OsSchedDeTaskFromTimeList(taskCB); - SET_SORTLIST_VALUE(&taskCB->sortList, responseTime); - taskCB->taskStatus |= OS_TASK_FLAG_FREEZE; - return; -} - -STATIC VOID SchedUnfreezeTask(LosTaskCB *taskCB) -{ - UINT64 currTime, responseTime; - - if (!(taskCB->taskStatus & OS_TASK_FLAG_FREEZE)) { - return; - } - - taskCB->taskStatus &= ~OS_TASK_FLAG_FREEZE; - currTime = OsGetCurrSchedTimeCycle(); - responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); - if (responseTime > currTime) { - OsSchedAddTask2TimeList(taskCB, responseTime); - return; - } - - SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); - if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { - LOS_ListDelete(&taskCB->pendList); - } - taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_PENDING); - return; -} - -VOID OsSchedSuspend(LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - OsSchedTaskDeQueue(taskCB); - } - - SchedFreezeTask(taskCB); - - taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED; - OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB); - if (taskCB == OsCurrTaskGet()) { - OsSchedResched(); - } -} - -BOOL OsSchedResume(LosTaskCB *taskCB) -{ - BOOL needSched = FALSE; - - SchedUnfreezeTask(taskCB); - - taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; - if (!OsTaskIsBlocked(taskCB)) { - OsSchedTaskEnQueue(taskCB); - needSched = TRUE; - } - - return needSched; + SCHEDULER_LOCK(intSave); + UINT64 deadline = runTask->ops->deadlineGet(runTask); + SCHEDULER_UNLOCK(intSave); + SchedNextExpireTimeSet(runTask->taskID, deadline, runTask->taskID); } -STATIC INLINE VOID SchedWakePendTimeTask(UINT64 currTime, LosTaskCB *taskCB, BOOL *needSchedule) +STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosTaskCB *taskCB, BOOL *needSched) { #ifndef LOSCFG_SCHED_DEBUG (VOID)currTime; @@ -522,19 +122,19 @@ STATIC INLINE VOID SchedWakePendTimeTask(UINT64 currTime, LosTaskCB *taskCB, BOO taskCB->schedStat.pendTime += currTime - taskCB->startTime; taskCB->schedStat.pendCount++; #endif - OsSchedTaskEnQueue(taskCB); - *needSchedule = TRUE; + taskCB->ops->enqueue(rq, taskCB); + *needSched = TRUE; } } LOS_SpinUnlock(&g_taskSpin); } -STATIC INLINE BOOL SchedScanTaskTimeList(SchedRunQue *rq) +STATIC INLINE BOOL SchedTimeoutQueueScan(SchedRunqueue *rq) { - BOOL needSchedule = FALSE; - SortLinkAttribute *taskSortLink = &rq->taskSortLink; - LOS_DL_LIST *listObject = &taskSortLink->sortLink; + BOOL needSched = FALSE; + SortLinkAttribute *timeoutQueue = &rq->timeoutQueue; + LOS_DL_LIST *listObject = &timeoutQueue->sortLink; /* * When task is pended with timeout, the task block is on the timeout sortlink * (per cpu) and ipc(mutex,sem and etc.)'s block at the same time, it can be waken @@ -543,23 +143,23 @@ STATIC INLINE BOOL SchedScanTaskTimeList(SchedRunQue *rq) * Now synchronize sortlink procedure is used, therefore the whole task scan needs * to be protected, preventing another core from doing sortlink deletion at same time. */ - LOS_SpinLock(&taskSortLink->spinLock); + LOS_SpinLock(&timeoutQueue->spinLock); if (LOS_ListEmpty(listObject)) { - LOS_SpinUnlock(&taskSortLink->spinLock); - return needSchedule; + LOS_SpinUnlock(&timeoutQueue->spinLock); + return needSched; } SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); UINT64 currTime = OsGetCurrSchedTimeCycle(); while (sortList->responseTime <= currTime) { LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(sortList, LosTaskCB, sortList); - OsDeleteNodeSortLink(taskSortLink, &taskCB->sortList); - LOS_SpinUnlock(&taskSortLink->spinLock); + OsDeleteNodeSortLink(timeoutQueue, &taskCB->sortList); + LOS_SpinUnlock(&timeoutQueue->spinLock); - SchedWakePendTimeTask(currTime, taskCB, &needSchedule); + SchedTimeoutTaskWake(rq, currTime, taskCB, &needSched); - LOS_SpinLock(&taskSortLink->spinLock); + LOS_SpinLock(&timeoutQueue->spinLock); if (LOS_ListEmpty(listObject)) { break; } @@ -567,17 +167,17 @@ STATIC INLINE BOOL SchedScanTaskTimeList(SchedRunQue *rq) sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); } - LOS_SpinUnlock(&taskSortLink->spinLock); + LOS_SpinUnlock(&timeoutQueue->spinLock); - return needSchedule; + return needSched; } VOID OsSchedTick(VOID) { - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); if (rq->responseID == OS_INVALID_VALUE) { - if (SchedScanTaskTimeList(rq)) { + if (SchedTimeoutQueueScan(rq)) { LOS_MpSchedule(OS_MP_CPU_ALL); rq->schedFlag |= INT_PEND_RESCH; } @@ -586,47 +186,34 @@ VOID OsSchedTick(VOID) rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; } -VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask) +VOID OsSchedResponseTimeReset(UINT64 responseTime) { - idleTask->basePrio = OS_TASK_PRIORITY_LOWEST; - idleTask->policy = LOS_SCHED_IDLE; - idleTask->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; - idleTask->timeSlice = idleTask->initTimeSlice; - OsSchedTaskEnQueue(idleTask); + OsSchedRunqueue()->responseTime = responseTime; } -VOID OsSchedResetSchedResponseTime(UINT64 responseTime) -{ - OsSchedRunQue()->responseTime = responseTime; -} - -VOID OsSchedRunQueInit(VOID) +VOID OsSchedRunqueueInit(VOID) { if (ArchCurrCpuid() != 0) { return; } for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { - SchedRunQue *rq = OsSchedRunQueByID(index); - OsSortLinkInit(&rq->taskSortLink); + SchedRunqueue *rq = OsSchedRunqueueByID(index); + OsSortLinkInit(&rq->timeoutQueue); rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; } } -VOID OsSchedRunQueIdleInit(UINT32 idleTaskID) +VOID OsSchedRunqueueIdleInit(UINT32 idleTaskID) { - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); rq->idleTaskID = idleTaskID; } UINT32 OsSchedInit(VOID) { - for (UINT16 index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) { - SchedQueue *queueList = &g_sched.queueList[index]; - LOS_DL_LIST *priList = &queueList->priQueueList[0]; - for (UINT16 pri = 0; pri < OS_PRIORITY_QUEUE_NUM; pri++) { - LOS_ListInit(&priList[pri]); - } + for (UINT16 cpuId = 0; cpuId < LOSCFG_KERNEL_CORE_NUM; cpuId++) { + HPFSchedPolicyInit(OsSchedRunqueueByID(cpuId)); } #ifdef LOSCFG_SCHED_TICK_DEBUG @@ -638,40 +225,69 @@ UINT32 OsSchedInit(VOID) return LOS_OK; } -STATIC LosTaskCB *GetTopTask(SchedRunQue *rq) +/* + * If the return value greater than 0, task1 has a lower priority than task2. + * If the return value less than 0, task1 has a higher priority than task2. + * If the return value is 0, task1 and task2 have the same priority. + */ +INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2) { - UINT32 priority, processPriority; - UINT32 bitmap; - LosTaskCB *newTask = NULL; - UINT32 processBitmap = g_sched.queueBitmap; -#ifdef LOSCFG_KERNEL_SMP - UINT32 cpuid = ArchCurrCpuid(); -#endif + SchedHPF *rp1 = (SchedHPF *)&task1->sp; + SchedHPF *rp2 = (SchedHPF *)&task2->sp; - while (processBitmap) { - processPriority = CLZ(processBitmap); - SchedQueue *queueList = &g_sched.queueList[processPriority]; - bitmap = queueList->queueBitmap; - while (bitmap) { - priority = CLZ(bitmap); - LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &queueList->priQueueList[priority], LosTaskCB, pendList) { -#ifdef LOSCFG_KERNEL_SMP - if (newTask->cpuAffiMask & (1U << cpuid)) { -#endif - goto FIND_TASK; -#ifdef LOSCFG_KERNEL_SMP - } -#endif - } - bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1)); - } - processBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - processPriority - 1)); + if (rp1->policy == rp2->policy) { + return task1->ops->schedParamCompare(&task1->sp, &task2->sp); + } + + if (rp1->policy == LOS_SCHED_IDLE) { + return 1; + } else if (rp2->policy == LOS_SCHED_IDLE) { + return -1; } + return 0; +} - newTask = OS_TCB_FROM_TID(rq->idleTaskID); +UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, const SchedParam *parentParam, const TSK_INIT_PARAM_S *param) +{ + switch (policy) { + case LOS_SCHED_FIFO: + case LOS_SCHED_RR: + HPFTaskSchedParamInit(taskCB, policy, parentParam, param); + break; + case LOS_SCHED_IDLE: + IdleTaskSchedParamInit(taskCB); + break; + default: + return LOS_NOK; + } + + return LOS_OK; +} -FIND_TASK: - OsSchedTaskDeQueue(newTask); +VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param) +{ + switch (policy) { + case LOS_SCHED_FIFO: + case LOS_SCHED_RR: + HPFProcessDefaultSchedParamGet(param); + break; + case LOS_SCHED_IDLE: + default: + PRINT_ERR("Invalid process-level scheduling policy, %u\n", policy); + break; + } + return; +} + +STATIC LosTaskCB *TopTaskGet(SchedRunqueue *rq) +{ + LosTaskCB *newTask = HPFRunqueueTopTaskGet(rq->hpfRunqueue); + + if (newTask == NULL) { + newTask = OS_TCB_FROM_TID(rq->idleTaskID); + } + + newTask->ops->start(rq, newTask); return newTask; } @@ -686,8 +302,8 @@ VOID OsSchedStart(VOID) OsTickStart(); - SchedRunQue *rq = OsSchedRunQue(); - LosTaskCB *newTask = GetTopTask(rq); + SchedRunqueue *rq = OsSchedRunqueue(); + LosTaskCB *newTask = TopTaskGet(rq); newTask->taskStatus |= OS_TASK_STATUS_RUNNING; #ifdef LOSCFG_KERNEL_SMP @@ -708,7 +324,8 @@ VOID OsSchedStart(VOID) OS_SCHEDULER_SET(cpuid); rq->responseID = OS_INVALID; - SchedSetNextExpireTime(newTask->taskID, newTask->startTime + newTask->timeSlice, OS_INVALID); + UINT64 deadline = newTask->ops->deadlineGet(newTask); + SchedNextExpireTimeSet(newTask->taskID, deadline, OS_INVALID); OsTaskContextLoad(newTask); } @@ -746,10 +363,8 @@ STATIC INLINE VOID SchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) OsHookCall(LOS_HOOK_TYPE_TASK_SWITCHEDIN, newTask, runTask); } -STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) +STATIC VOID SchedTaskSwitch(SchedRunqueue *rq, LosTaskCB *runTask, LosTaskCB *newTask) { - UINT64 endTime; - SchedSwitchCheck(runTask, newTask); runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING; @@ -782,19 +397,15 @@ STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) /* The currently running task is blocked */ newTask->startTime = OsGetCurrSchedTimeCycle(); /* The task is in a blocking state and needs to update its time slice before pend */ - TimeSliceUpdate(runTask, newTask->startTime); + runTask->ops->timeSliceUpdate(rq, runTask, newTask->startTime); if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) { - OsSchedAddTask2TimeList(runTask, runTask->startTime + runTask->waitTime); + OsSchedTimeoutQueueAdd(runTask, runTask->startTime + runTask->waitTime); } } - if (newTask->policy == LOS_SCHED_RR) { - endTime = newTask->startTime + newTask->timeSlice; - } else { - endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; - } - SchedSetNextExpireTime(newTask->taskID, endTime, runTask->taskID); + UINT64 deadline = newTask->ops->deadlineGet(newTask); + SchedNextExpireTimeSet(newTask->taskID, deadline, runTask->taskID); #ifdef LOSCFG_SCHED_DEBUG newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime; @@ -808,24 +419,21 @@ STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) VOID OsSchedIrqEndCheckNeedSched(VOID) { - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); LosTaskCB *runTask = OsCurrTaskGet(); - TimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); - if (runTask->timeSlice <= OS_TIME_SLICE_MIN) { - rq->schedFlag |= INT_PEND_RESCH; - } + runTask->ops->timeSliceUpdate(rq, runTask, OsGetCurrSchedTimeCycle()); if (OsPreemptable() && (rq->schedFlag & INT_PEND_RESCH)) { rq->schedFlag &= ~INT_PEND_RESCH; LOS_SpinLock(&g_taskSpin); - OsSchedTaskEnQueue(runTask); + runTask->ops->enqueue(rq, runTask); - LosTaskCB *newTask = GetTopTask(rq); + LosTaskCB *newTask = TopTaskGet(rq); if (runTask != newTask) { - SchedTaskSwitch(runTask, newTask); + SchedTaskSwitch(rq, runTask, newTask); LOS_SpinUnlock(&g_taskSpin); return; } @@ -834,14 +442,14 @@ VOID OsSchedIrqEndCheckNeedSched(VOID) } if (rq->schedFlag & INT_PEND_TICK) { - OsSchedUpdateExpireTime(); + OsSchedExpireTimeUpdate(); } } VOID OsSchedResched(VOID) { LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); #ifdef LOSCFG_KERNEL_SMP LOS_ASSERT(rq->taskLockCnt == 1); #else @@ -850,21 +458,22 @@ VOID OsSchedResched(VOID) rq->schedFlag &= ~INT_PEND_RESCH; LosTaskCB *runTask = OsCurrTaskGet(); - LosTaskCB *newTask = GetTopTask(rq); + LosTaskCB *newTask = TopTaskGet(rq); if (runTask == newTask) { return; } - SchedTaskSwitch(runTask, newTask); + SchedTaskSwitch(rq, runTask, newTask); } VOID LOS_Schedule(VOID) { UINT32 intSave; LosTaskCB *runTask = OsCurrTaskGet(); + SchedRunqueue *rq = OsSchedRunqueue(); if (OS_INT_ACTIVE) { - OsSchedRunQuePendingSet(); + OsSchedRunqueuePendingSet(); return; } @@ -879,10 +488,10 @@ VOID LOS_Schedule(VOID) */ SCHEDULER_LOCK(intSave); - TimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); + runTask->ops->timeSliceUpdate(rq, runTask, OsGetCurrSchedTimeCycle()); /* add run task back to ready queue */ - OsSchedTaskEnQueue(runTask); + runTask->ops->enqueue(rq, runTask); /* reschedule to new thread */ OsSchedResched(); @@ -890,44 +499,40 @@ VOID LOS_Schedule(VOID) SCHEDULER_UNLOCK(intSave); } -STATIC INLINE LOS_DL_LIST *OsSchedLockPendFindPosSub(const LosTaskCB *runTask, const LOS_DL_LIST *lockList) +STATIC INLINE LOS_DL_LIST *SchedLockPendFindPosSub(const LosTaskCB *runTask, const LOS_DL_LIST *lockList) { LosTaskCB *pendedTask = NULL; - LOS_DL_LIST *node = NULL; LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, lockList, LosTaskCB, pendList) { - if (pendedTask->priority < runTask->priority) { + INT32 ret = OsSchedParamCompare(pendedTask, runTask); + if (ret < 0) { continue; - } else if (pendedTask->priority > runTask->priority) { - node = &pendedTask->pendList; - break; + } else if (ret > 0) { + return &pendedTask->pendList; } else { - node = pendedTask->pendList.pstNext; - break; + return pendedTask->pendList.pstNext; } } - - return node; + return NULL; } LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList) { - LOS_DL_LIST *node = NULL; - if (LOS_ListEmpty(lockList)) { - node = lockList; - } else { - LosTaskCB *pendedTask1 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(lockList)); - LosTaskCB *pendedTask2 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_LAST(lockList)); - if (pendedTask1->priority > runTask->priority) { - node = lockList->pstNext; - } else if (pendedTask2->priority <= runTask->priority) { - node = lockList; - } else { - node = OsSchedLockPendFindPosSub(runTask, lockList); - } + return lockList; } - return node; -} + LosTaskCB *pendedTask1 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(lockList)); + INT32 ret = OsSchedParamCompare(pendedTask1, runTask); + if (ret > 0) { + return lockList->pstNext; + } + LosTaskCB *pendedTask2 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_LAST(lockList)); + ret = OsSchedParamCompare(pendedTask2, runTask); + if (ret <= 0) { + return lockList; + } + + return SchedLockPendFindPosSub(runTask, lockList); +} diff --git a/kernel/base/sched/los_sortlink.c b/kernel/base/sched/los_sortlink.c index ffad8838..4f68436f 100644 --- a/kernel/base/sched/los_sortlink.c +++ b/kernel/base/sched/los_sortlink.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -30,7 +30,6 @@ */ #include "los_sortlink_pri.h" -#include "los_mp.h" VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader) { diff --git a/kernel/base/sched/los_statistics.c b/kernel/base/sched/los_statistics.c index fff5273e..1825a0dc 100644 --- a/kernel/base/sched/los_statistics.c +++ b/kernel/base/sched/los_statistics.c @@ -55,7 +55,7 @@ UINT32 OsSchedDebugInit(VOID) VOID OsSchedDebugRecordData(VOID) { - SchedRunQue *rq = OsSchedRunQue(); + SchedRunqueue *rq = OsSchedRunqueue(); SchedTickDebug *schedDebug = &g_schedTickDebug[ArchCurrCpuid()]; UINT64 currTime = OsGetCurrSchedTimeCycle(); LOS_ASSERT(currTime >= rq->responseTime); @@ -131,8 +131,8 @@ UINT32 OsShellShowSchedStatistics(VOID) SCHEDULER_LOCK(intSave); for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { - SchedRunQue *rq = OsSchedRunQueByID(cpu); - taskLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->taskSortLink); + SchedRunqueue *rq = OsSchedRunqueueByID(cpu); + taskLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->timeoutQueue); } SCHEDULER_UNLOCK(intSave); diff --git a/kernel/common/los_config.c b/kernel/common/los_config.c index a00be129..e0bbccce 100644 --- a/kernel/common/los_config.c +++ b/kernel/common/los_config.c @@ -70,7 +70,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 EarliestInit(VOID) /* Must be placed at the beginning of the boot process */ OsSetMainTask(); OsCurrTaskSet(OsGetMainTask()); - OsSchedRunQueInit(); + OsSchedRunqueueInit(); g_sysClock = OS_SYS_CLOCK; g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND; diff --git a/kernel/common/los_config.h b/kernel/common/los_config.h index 4182458a..f9556c73 100644 --- a/kernel/common/los_config.h +++ b/kernel/common/los_config.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -272,6 +272,15 @@ extern UINT32 __heap_end; #define LOSCFG_BASE_IPC_MUX #endif +/****************************** rwlock module configuration ******************************/ +/** + * @ingroup los_config + * Configuration item for rwlock module tailoring + */ +#ifndef LOSCFG_BASE_IPC_RWLOCK +#define LOSCFG_BASE_IPC_RWLOCK +#endif + /****************************** Queue module configuration ********************************/ /** * @ingroup los_config diff --git a/kernel/extended/liteipc/hm_liteipc.c b/kernel/extended/liteipc/hm_liteipc.c index 03d0eefe..3642c896 100644 --- a/kernel/extended/liteipc/hm_liteipc.c +++ b/kernel/extended/liteipc/hm_liteipc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -1054,7 +1054,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content) OsHookCall(LOS_HOOK_TYPE_IPC_WRITE, &buf->msg, dstTid, tcb->processID, tcb->waitFlag); if (tcb->waitFlag == OS_TASK_WAIT_LITEIPC) { OsTaskWakeClearPendMask(tcb); - OsSchedTaskWake(tcb); + tcb->ops->wake(tcb); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); LOS_Schedule(); @@ -1138,7 +1138,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcRead(IpcContent *content) if (LOS_ListEmpty(listHead)) { OsTaskWaitSetPendMask(OS_TASK_WAIT_LITEIPC, OS_INVALID_VALUE, timeout); OsHookCall(LOS_HOOK_TYPE_IPC_TRY_READ, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); - ret = OsSchedTaskWait(&g_ipcPendlist, timeout, TRUE); + ret = tcb->ops->wait(tcb, &g_ipcPendlist, timeout); if (ret == LOS_ERRNO_TSK_TIMEOUT) { OsHookCall(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); SCHEDULER_UNLOCK(intSave); diff --git a/kernel/extended/power/los_pm.c b/kernel/extended/power/los_pm.c index 807ccaa5..860e7c8a 100644 --- a/kernel/extended/power/los_pm.c +++ b/kernel/extended/power/los_pm.c @@ -207,8 +207,8 @@ STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm) tickTimerStop = OsPmTickTimerStop(pm); if (!tickTimerStop) { - OsSchedResetSchedResponseTime(0); - OsSchedUpdateExpireTime(); + OsSchedResponseTimeReset(0); + OsSchedExpireTimeUpdate(); } OsPmCpuSuspend(pm); diff --git a/kernel/extended/trace/cnv/trace_cnv.c b/kernel/extended/trace/cnv/trace_cnv.c index 0a20b824..1ade59c6 100644 --- a/kernel/extended/trace/cnv/trace_cnv.c +++ b/kernel/extended/trace/cnv/trace_cnv.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -155,12 +155,25 @@ STATIC VOID LOS_TraceMuxDelete(const LosMux *muxCB) STATIC VOID LOS_TraceTaskCreate(const LosTaskCB *taskCB) { - LOS_TRACE(TASK_CREATE, taskCB->taskID, taskCB->taskStatus, taskCB->priority); +#ifdef LOSCFG_KERNEL_TRACE + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + LOS_TRACE(TASK_CREATE, taskCB->taskID, taskCB->taskStatus, param.priority); +#else + (VOID)taskCB; +#endif } STATIC VOID LOS_TraceTaskPriModify(const LosTaskCB *taskCB, UINT32 prio) { - LOS_TRACE(TASK_PRIOSET, taskCB->taskID, taskCB->taskStatus, taskCB->priority, prio); +#ifdef LOSCFG_KERNEL_TRACE + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + LOS_TRACE(TASK_PRIOSET, taskCB->taskID, taskCB->taskStatus, param.priority, prio); +#else + (VOID)taskCB; + (VOID)prio; +#endif } STATIC VOID LOS_TraceTaskDelete(const LosTaskCB *taskCB) @@ -170,13 +183,28 @@ STATIC VOID LOS_TraceTaskDelete(const LosTaskCB *taskCB) STATIC VOID LOS_TraceTaskSwitchedIn(const LosTaskCB *newTask, const LosTaskCB *runTask) { - LOS_TRACE(TASK_SWITCH, newTask->taskID, runTask->priority, runTask->taskStatus, - newTask->priority, newTask->taskStatus); +#ifdef LOSCFG_KERNEL_TRACE + SchedParam runParam = { 0 }; + SchedParam newParam = { 0 }; + runTask->ops->schedParamGet(runTask, &runParam); + newTask->ops->schedParamGet(newTask, &newParam); + LOS_TRACE(TASK_SWITCH, newTask->taskID, runParam.priority, runTask->taskStatus, + newParam.priority, newTask->taskStatus); +#else + (VOID)newTask; + (VOID)runTask; +#endif } STATIC VOID LOS_TraceTaskResume(const LosTaskCB *taskCB) { - LOS_TRACE(TASK_RESUME, taskCB->taskID, taskCB->taskStatus, taskCB->priority); +#ifdef LOSCFG_KERNEL_TRACE + SchedParam param = { 0 }; + taskCB->ops->schedParamGet(taskCB, ¶m); + LOS_TRACE(TASK_RESUME, taskCB->taskID, taskCB->taskStatus, param.priority); +#else + (VOID)taskCB; +#endif } STATIC VOID LOS_TraceTaskSuspend(const LosTaskCB *taskCB) diff --git a/kernel/extended/trace/los_trace.c b/kernel/extended/trace/los_trace.c index d7d34eae..7ece4516 100644 --- a/kernel/extended/trace/los_trace.c +++ b/kernel/extended/trace/los_trace.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -126,10 +126,12 @@ STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR id VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb) { errno_t ret; + SchedParam param = { 0 }; (VOID)memset_s(obj, sizeof(ObjData), 0, sizeof(ObjData)); obj->id = OsTraceGetMaskTid(tcb->taskID); - obj->prio = tcb->priority; + tcb->ops->schedParamGet(tcb, ¶m); + obj->prio = param.priority; ret = strncpy_s(obj->name, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE, tcb->taskName, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE - 1); if (ret != EOK) { diff --git a/syscall/process_syscall.c b/syscall/process_syscall.c index 59165d2b..bc6aeffb 100644 --- a/syscall/process_syscall.c +++ b/syscall/process_syscall.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -64,6 +64,7 @@ static int OsUserTaskSchedulerSet(unsigned int tid, unsigned short policy, unsig int ret; unsigned int intSave; bool needSched = false; + SchedParam param = { 0 }; if (OS_TID_CHECK_INVALID(tid)) { return EINVAL; @@ -85,8 +86,10 @@ static int OsUserTaskSchedulerSet(unsigned int tid, unsigned short policy, unsig return ret; } - policy = (policyFlag == true) ? policy : taskCB->policy; - needSched = OsSchedModifyTaskSchedParam(taskCB, policy, priority); + taskCB->ops->schedParamGet(taskCB, ¶m); + param.policy = (policyFlag == true) ? policy : param.policy; + param.priority = priority; + needSched = taskCB->ops->schedParamModify(taskCB, ¶m); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); @@ -108,7 +111,7 @@ void SysSchedYield(int type) int SysSchedGetScheduler(int id, int flag) { unsigned int intSave; - int policy; + SchedParam param = { 0 }; int ret; if (flag < 0) { @@ -124,9 +127,9 @@ int SysSchedGetScheduler(int id, int flag) return -ret; } - policy = (int)taskCB->policy; + taskCB->ops->schedParamGet(taskCB, ¶m); SCHEDULER_UNLOCK(intSave); - return policy; + return (int)param.policy; } return LOS_GetProcessScheduler(id); @@ -158,7 +161,7 @@ int SysSchedSetScheduler(int id, int policy, int prio, int flag) int SysSchedGetParam(int id, int flag) { - int prio; + SchedParam param = { 0 }; unsigned int intSave; if (flag < 0) { @@ -168,15 +171,15 @@ int SysSchedGetParam(int id, int flag) LosTaskCB *taskCB = OS_TCB_FROM_TID(id); SCHEDULER_LOCK(intSave); - prio = OsUserTaskOperatePermissionsCheck(taskCB); - if (prio != LOS_OK) { + int ret = OsUserTaskOperatePermissionsCheck(taskCB); + if (ret != LOS_OK) { SCHEDULER_UNLOCK(intSave); - return -prio; + return -ret; } - prio = (int)taskCB->priority; + taskCB->ops->schedParamGet(taskCB, ¶m); SCHEDULER_UNLOCK(intSave); - return prio; + return (int)param.priority; } if (id == 0) { @@ -250,6 +253,7 @@ int SysSchedRRGetInterval(int pid, struct timespec *tp) { unsigned int intSave; int ret; + SchedParam param = { 0 }; time_t timeSlice = 0; struct timespec tv; LosTaskCB *taskCB = NULL; @@ -277,8 +281,11 @@ int SysSchedRRGetInterval(int pid, struct timespec *tp) } LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { - if (!OsTaskIsInactive(taskCB) && (taskCB->policy == LOS_SCHED_RR)) { - timeSlice += taskCB->initTimeSlice; + if (!OsTaskIsInactive(taskCB)) { + taskCB->ops->schedParamGet(taskCB, ¶m); + if (param.policy == LOS_SCHED_RR) { + timeSlice += param.timeSlice; + } } } diff --git a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c index 01d0f217..26ef5a45 100644 --- a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c +++ b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_101.c @@ -97,7 +97,7 @@ static UINT32 Testcase(void) ICUNIT_GOTO_NOT_EQUAL((ret & OS_TASK_STATUS_READY), 0, ret, EXIT); /* check if other core is Task_locked */ - gTestTaskLock = OsSchedRunQueByID((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM))->taskLockCnt; + gTestTaskLock = OsSchedRunqueueByID((ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM))->taskLockCnt; ICUNIT_ASSERT_NOT_EQUAL(gTestTaskLock, 0, gTestTaskLock); ret = LOS_TaskSuspend(g_testTaskID02); diff --git a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c index ef190e86..26de0819 100644 --- a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c +++ b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_127.c @@ -44,7 +44,7 @@ static void HwiF01(void) UINT32 gTestSwtmrTaskID; UINT32 cpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); - gTestIdleTaskID = OsSchedRunQueByID(cpuid)->idleTaskID; + gTestIdleTaskID = OsSchedRunqueueByID(cpuid)->idleTaskID; ret = LOS_TaskDelete(gTestIdleTaskID); ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); diff --git a/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp b/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp index dd790bc5..08995680 100644 --- a/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp +++ b/testsuites/unittest/process/basic/process/smoke/process_test_044.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -51,7 +51,7 @@ static int GroupProcess(void) ret = sched_rr_get_interval(getpid(), &ts); ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ts.tv_sec, 0, ts.tv_sec); - if (ts.tv_nsec <= 5000000 || ts.tv_nsec > 20000000) { // 5000000, 20000000, expected range of tv_nsec. + if (ts.tv_nsec < 5000000 || ts.tv_nsec > 20000000) { // 5000000, 20000000, expected range of tv_nsec. ICUNIT_ASSERT_EQUAL(ts.tv_nsec, -1, ts.tv_nsec); } @@ -61,7 +61,7 @@ static int GroupProcess(void) ret = sched_rr_get_interval(getpid(), &ts); ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ts.tv_sec, 0, ts.tv_sec); - if (ts.tv_nsec <= 10000000 || ts.tv_nsec > 40000000) { // 10000000, 40000000, expected range of tv_nsec. + if (ts.tv_nsec < 10000000 || ts.tv_nsec > 40000000) { // 10000000, 40000000, expected range of tv_nsec. ICUNIT_ASSERT_EQUAL(ts.tv_nsec, -1, ts.tv_nsec); } -- GitLab