diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index 14409967..4aad1496 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -33,6 +33,7 @@ #include "los_memory_pri.h" #include "los_printf_pri.h" #include "los_task_pri.h" +#include "los_percpu_pri.h" #include "los_hw_pri.h" #ifdef LOSCFG_SAVE_EXCINFO #include "los_excinfo_pri.h" @@ -58,6 +59,7 @@ #include "los_bitmap.h" #include "los_process_pri.h" #include "los_exc_pri.h" +#include "los_sched_pri.h" #ifdef LOSCFG_FS_VFS #include "console.h" #endif @@ -191,7 +193,7 @@ UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT3 return LOS_ERRNO_VM_NOT_FOUND; } #if defined(LOSCFG_KERNEL_SMP) && defined(LOSCFG_DEBUG_VERSION) - BOOL irqEnable = !(LOS_SpinHeld(&g_taskSpin) && (OsPercpuGet()->taskLockCnt != 0)); + BOOL irqEnable = !(LOS_SpinHeld(&g_taskSpin) && OsSchedIsLock()); if (irqEnable) { ArchIrqEnable(); } else { @@ -535,9 +537,9 @@ STATIC VOID OsExcRestore(VOID) g_intCount[currCpuID] = 0; g_curNestCount[currCpuID] = 0; #ifdef LOSCFG_KERNEL_SMP - OsPercpuGet()->excFlag = CPU_RUNNING; + OsCpuStatusSet(CPU_RUNNING); #endif - OsPercpuGet()->taskLockCnt = 0; + OsSchedLockSet(0); } STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) @@ -977,28 +979,6 @@ VOID OsDataAbortExcHandleEntry(ExcContext *excBufAddr) #define EXC_WAIT_INTER 50U #define EXC_WAIT_TIME 2000U -STATIC VOID OsAllCpuStatusOutput(VOID) -{ - UINT32 i; - - for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { - switch (g_percpu[i].excFlag) { - case CPU_RUNNING: - PrintExcInfo("cpu%u is running.\n", i); - break; - case CPU_HALT: - PrintExcInfo("cpu%u is halted.\n", i); - break; - case CPU_EXC: - PrintExcInfo("cpu%u is in exc.\n", i); - break; - default: - break; - } - } - PrintExcInfo("The current handling the exception is cpu%u !\n", ArchCurrCpuid()); -} - STATIC VOID WaitAllCpuStop(UINT32 cpuID) { UINT32 i; @@ -1006,7 +986,7 @@ STATIC VOID WaitAllCpuStop(UINT32 cpuID) while (time < EXC_WAIT_TIME) { for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { - if ((i != cpuID) && (g_percpu[i].excFlag != CPU_HALT)) { + if ((i != cpuID) && !OsCpuStatusIsHalt(i)) { LOS_Mdelay(EXC_WAIT_INTER); time += EXC_WAIT_INTER; break; @@ -1044,7 +1024,7 @@ STATIC VOID OsCheckAllCpuStatus(VOID) UINT32 currCpuID = ArchCurrCpuid(); UINT32 ret, target; - OsPercpuGet()->excFlag = CPU_EXC; + OsCpuStatusSet(CPU_EXC); LOCKDEP_CLEAR_LOCKS(); LOS_SpinLock(&g_excSerializerSpin); @@ -1152,15 +1132,15 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsPrintExcHead(UINT32 far) STATIC VOID OsSysStateSave(UINT32 *intCount, UINT32 *lockCount) { *intCount = g_intCount[ArchCurrCpuid()]; - *lockCount = OsPercpuGet()->taskLockCnt; + *lockCount = OsSchedLockCountGet(); g_intCount[ArchCurrCpuid()] = 0; - OsPercpuGet()->taskLockCnt = 0; + OsSchedLockSet(0); } STATIC VOID OsSysStateRestore(UINT32 intCount, UINT32 lockCount) { g_intCount[ArchCurrCpuid()] = intCount; - OsPercpuGet()->taskLockCnt = lockCount; + OsSchedLockSet(lockCount); } #endif @@ -1177,7 +1157,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, ExcContext *excBufAd #endif /* Task scheduling is not allowed during exception handling */ - OsPercpuGet()->taskLockCnt++; + OsSchedLock(); g_curNestCount[ArchCurrCpuid()]++; diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 1f0b059d..60757ff7 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -810,7 +810,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; g_processGroup = kerInitProcess->group; LOS_ListInit(&g_processGroup->groupList); - OsCurrProcessSet(kerInitProcess); LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess); ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, OS_TASK_PRIORITY_LOWEST, "KIdle"); @@ -832,7 +831,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) if (ret != LOS_OK) { return ret; } - idleProcess->threadGroupID = OsPercpuGet()->idleTaskID; + idleProcess->threadGroupID = OsGetIdleTaskId(); return LOS_OK; } @@ -907,7 +906,7 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio } #endif - needSched = OsSchedModifyProcessSchedParam(processCB, policy, prio); + needSched = OsSchedModifyProcessSchedParam(pid, policy, prio); SCHEDULER_UNLOCK(intSave); LOS_MpSchedule(OS_MP_CPU_ALL); diff --git a/kernel/base/core/los_smp.c b/kernel/base/core/los_smp.c index d92c7f55..01b919a6 100644 --- a/kernel/base/core/los_smp.c +++ b/kernel/base/core/los_smp.c @@ -45,8 +45,6 @@ STATIC VOID OsSmpSecondaryInit(VOID *arg) { UNUSED(arg); - OsCurrProcessSet(OS_PCB_FROM_PID(OsGetKernelInitProcessID())); - #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE OsSwtmrInit(); #endif diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index 455d0e57..9b1161ec 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -52,13 +52,13 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin); #define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state)) #define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state)) -LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) +STATIC VOID SwtmrTask(VOID) { SwtmrHandlerItemPtr swtmrHandlePtr = NULL; SwtmrHandlerItem swtmrHandle; UINT32 ret, swtmrHandlerQueue; - swtmrHandlerQueue = OsPercpuGet()->swtmrHandlerQueue; + swtmrHandlerQueue = OsSchedSwtmrHandlerQueueGet(); for (;;) { ret = LOS_QueueRead(swtmrHandlerQueue, &swtmrHandlePtr, sizeof(CHAR *), LOS_WAIT_FOREVER); if ((ret == LOS_OK) && (swtmrHandlePtr != NULL)) { @@ -72,14 +72,13 @@ LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) } } -LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) +STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID) { - UINT32 ret, swtmrTaskID; + UINT32 ret; TSK_INIT_PARAM_S swtmrTask; - UINT32 cpuid = ArchCurrCpuid(); (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask; + swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask; swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; swtmrTask.pcName = "Swt_Task"; swtmrTask.usTaskPrio = 0; @@ -87,15 +86,22 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) #ifdef LOSCFG_KERNEL_SMP swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid); #endif - ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask); + ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask); if (ret == LOS_OK) { - g_percpu[cpuid].swtmrTaskID = swtmrTaskID; - OS_TCB_FROM_TID(swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; + OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; } return ret; } +BOOL OsIsSwtmrTask(const LosTaskCB *taskCB) +{ + if (taskCB->taskEntry == (TSK_ENTRY_FUNC)SwtmrTask) { + return TRUE; + } + return FALSE; +} + LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID) { for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) { @@ -113,6 +119,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) SWTMR_CTRL_S *swtmr = NULL; UINT32 swtmrHandlePoolSize; UINT32 cpuid = ArchCurrCpuid(); + UINT32 swtmrTaskID, swtmrHandlerQueue; + if (cpuid == 0) { size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT; swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */ @@ -142,31 +150,21 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) ret = LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM; goto ERROR; } - - ret = OsSchedSwtmrScanRegister((SchedScan)OsSwtmrScan); - if (ret != LOS_OK) { - goto ERROR; - } } - ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &g_percpu[cpuid].swtmrHandlerQueue, 0, sizeof(CHAR *)); + ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &swtmrHandlerQueue, 0, sizeof(CHAR *)); if (ret != LOS_OK) { ret = LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED; goto ERROR; } - ret = OsSwtmrTaskCreate(); + ret = SwtmrTaskCreate(cpuid, &swtmrTaskID); if (ret != LOS_OK) { ret = LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; goto ERROR; } - ret = OsSortLinkInit(&g_percpu[cpuid].swtmrSortLink); - if (ret != LOS_OK) { - ret = LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED; - goto ERROR; - } - + OsSchedRunQueSwtmrInit(swtmrTaskID, swtmrHandlerQueue); return LOS_OK; ERROR: @@ -178,7 +176,7 @@ ERROR: * Description: Start Software Timer * Input : swtmr --- Need to start software timer */ -LITE_OS_SEC_TEXT VOID OsSwtmrStart(UINT64 currTime, SWTMR_CTRL_S *swtmr) +LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) { UINT32 ticks; @@ -191,8 +189,8 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(UINT64 currTime, SWTMR_CTRL_S *swtmr) } swtmr->ucState = OS_SWTMR_STATUS_TICKING; - OsAdd2SortLink(&swtmr->stSortList, swtmr->startTime, ticks, OS_SORT_LINK_SWTMR); - OsSchedUpdateExpireTime(currTime); + OsSchedAddSwtmr2TimeList(&swtmr->stSortList, swtmr->startTime, ticks); + OsSchedUpdateExpireTime(); return; } @@ -208,15 +206,18 @@ STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) swtmr->uwOwnerPid = 0; } -STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, UINT64 currTime, SWTMR_CTRL_S *swtmr) +VOID OsSwtmrWake(SchedRunQue *rq, UINT64 startTime, SortLinkList *sortList) { + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + + OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr); LOS_SpinLock(&g_swtmrSpin); SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); if (swtmrHandler != NULL) { swtmrHandler->handler = swtmr->pfnHandler; swtmrHandler->arg = swtmr->uwArg; - if (LOS_QueueWrite(cpu->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) { + if (LOS_QueueWrite(rq->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) { (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandler); } } @@ -233,81 +234,32 @@ STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, UINT64 currTime, SWTMR_CTRL_ swtmr->ucState = OS_SWTMR_STATUS_CREATED; } else { swtmr->uwOverrun++; - OsSwtmrStart(currTime, swtmr); + swtmr->startTime = startTime; + OsSwtmrStart(swtmr); } LOS_SpinUnlock(&g_swtmrSpin); } -/* - * Description: Tick interrupt interface module of software timer - * Return : LOS_OK on success or error code on failure - */ -LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) -{ - Percpu *cpu = OsPercpuGet(); - SortLinkAttribute* swtmrSortLink = &cpu->swtmrSortLink; - LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; - - /* - * it needs to be carefully coped with, since the swtmr is in specific sortlink - * while other cores still has the chance to process it, like stop the timer. - */ - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - - if (LOS_ListEmpty(listObject)) { - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - return; - } - SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); - - UINT64 currTime = OsGetCurrSchedTimeCycle(); - while (sortList->responseTime <= currTime) { - sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); - SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); - swtmr->startTime = GET_SORTLIST_VALUE(sortList); - OsDeleteNodeSortLink(swtmrSortLink, sortList); - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - - OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr); - OsWakePendTimeSwtmr(cpu, currTime, swtmr); - - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - if (LOS_ListEmpty(listObject)) { - break; - } - - sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); - } - - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); -} - -LITE_OS_SEC_TEXT VOID OsSwtmrResponseTimeReset(UINT64 startTime) +VOID OsSwtmrRestart(UINT64 startTime, SortLinkList *sortList) { UINT32 intSave; - Percpu *cpu = OsPercpuGet(); - SortLinkAttribute* swtmrSortLink = &cpu->swtmrSortLink; - LOS_DL_LIST *listHead = &swtmrSortLink->sortLink; - LOS_DL_LIST *listNext = listHead->pstNext; - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - while (listNext != listHead) { - SortLinkList *sortList = LOS_DL_LIST_ENTRY(listNext, SortLinkList, sortLinkNode); - OsDeleteNodeSortLink(swtmrSortLink, sortList); - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + SWTMR_LOCK(intSave); + swtmr->startTime = startTime; + OsSwtmrStart(swtmr); + SWTMR_UNLOCK(intSave); +} - SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); +BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +{ + UINT32 intSave; - SWTMR_LOCK(intSave); - swtmr->startTime = startTime; - OsSwtmrStart(startTime, swtmr); - SWTMR_UNLOCK(intSave); - - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - listNext = listNext->pstNext; - } - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); + SWTMR_LOCK(intSave); + BOOL find = OsSchedSwtmrTimeListFind(checkFunc, arg); + SWTMR_UNLOCK(intSave); + return find; } /* @@ -316,7 +268,8 @@ LITE_OS_SEC_TEXT VOID OsSwtmrResponseTimeReset(UINT64 startTime) */ LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) { - return OsSortLinkGetNextExpireTime(&OsPercpuGet()->swtmrSortLink); + UINT64 currTime = OsGetCurrSchedTimeCycle(); + return (OsSortLinkGetNextExpireTime(currTime, &OsSchedRunQue()->swtmrSortLink) / OS_CYCLE_PER_TICK); } /* @@ -325,12 +278,12 @@ LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) */ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) { - OsDeleteSortLink(&swtmr->stSortList, OS_SORT_LINK_SWTMR); + OsSchedDeSwtmrFromTimeList(&swtmr->stSortList); swtmr->ucState = OS_SWTMR_STATUS_CREATED; swtmr->uwOverrun = 0; - OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle()); + OsSchedUpdateExpireTime(); } /* @@ -339,7 +292,8 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) */ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) { - return OsSortLinkGetTargetExpireTime(&swtmr->stSortList); + UINT64 currTime = OsGetCurrSchedTimeCycle(); + return (OsSortLinkGetTargetExpireTime(currTime, &swtmr->stSortList) / OS_CYCLE_PER_TICK); } LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, @@ -427,7 +381,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) /* fall-through */ case OS_SWTMR_STATUS_CREATED: swtmr->startTime = OsGetCurrSchedTimeCycle(); - OsSwtmrStart(swtmr->startTime, swtmr); + OsSwtmrStart(swtmr); break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 4145ae74..37f40492 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -94,6 +94,7 @@ VOID OsSetMainTask() 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].priority = OS_TASK_PRIORITY_LOWEST; #ifdef LOSCFG_KERNEL_SMP_LOCKDEP g_mainTask[i].lockDep.lockDepth = 0; @@ -216,16 +217,14 @@ EXIT: UINT32 OsGetIdleTaskId(VOID) { - Percpu *perCpu = OsPercpuGet(); - return perCpu->idleTaskID; + return OsSchedGetRunQueIdle(); } LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) { UINT32 ret; TSK_INIT_PARAM_S taskInitParam; - Percpu *perCpu = OsPercpuGet(); - UINT32 *idleTaskID = &perCpu->idleTaskID; + UINT32 idleTaskID; (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask; @@ -236,9 +235,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) #ifdef LOSCFG_KERNEL_SMP taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); #endif - ret = LOS_TaskCreateOnly(idleTaskID, &taskInitParam); - LosTaskCB *idleTask = OS_TCB_FROM_TID(*idleTaskID); + ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam); + LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID); idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; + OsSchedRunQueIdleInit(idleTaskID); OsSchedSetIdleTaskSchedParam(idleTask); return ret; @@ -968,11 +968,6 @@ LITE_OS_SEC_TEXT UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UIN SCHEDULER_LOCK(intSave); } -#ifdef LOSCFG_KERNEL_SMP - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 1); -#else - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0); -#endif OsRunTaskToDelete(taskCB); EXIT: @@ -1149,13 +1144,21 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID) UINT32 intSave; intSave = LOS_IntLock(); - OsCpuSchedLock(OsPercpuGet()); + OsSchedLock(); LOS_IntRestore(intSave); } LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) { - OsCpuSchedUnlock(OsPercpuGet(), LOS_IntLock()); + UINT32 intSave; + + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + + if (needSched) { + LOS_Schedule(); + } } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo) diff --git a/kernel/base/include/los_percpu_pri.h b/kernel/base/include/los_percpu_pri.h index e63aa450..8a824ffd 100644 --- a/kernel/base/include/los_percpu_pri.h +++ b/kernel/base/include/los_percpu_pri.h @@ -34,8 +34,6 @@ #include "los_base.h" #include "los_hw_cpu.h" -#include "los_spinlock.h" -#include "los_sortlink_pri.h" #ifdef __cplusplus #if __cplusplus @@ -49,29 +47,11 @@ typedef enum { CPU_HALT, /* cpu in the halt */ CPU_EXC /* cpu in the exc */ } ExcFlag; -#endif typedef struct { - SortLinkAttribute taskSortLink; /* task sort link */ - SPIN_LOCK_S taskSortLinkSpin; /* task sort link spin lock */ - SortLinkAttribute swtmrSortLink; /* swtmr sort link */ - SPIN_LOCK_S swtmrSortLinkSpin; /* swtmr sort link spin lock */ - UINT64 responseTime; /* Response time for current CPU tick interrupts */ - UINT64 tickStartTime; /* The time when the tick interrupt starts processing */ - UINT32 responseID; /* The response ID of the current CPU tick interrupt */ - UINTPTR runProcess; /* The address of the process control block pointer to which - the current CPU is running */ - UINT32 idleTaskID; /* idle task id */ - UINT32 taskLockCnt; /* task lock flag */ - UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ - UINT32 swtmrTaskID; /* software timer task id */ - - UINT32 schedFlag; /* pending scheduler flag */ -#ifdef LOSCFG_KERNEL_SMP - UINT32 excFlag; /* cpu halt or exc flag */ + UINT32 excFlag; /* cpu halt or exc flag */ #ifdef LOSCFG_KERNEL_SMP_CALL - LOS_DL_LIST funcLink; /* mp function call link */ -#endif + LOS_DL_LIST funcLink; /* mp function call link */ #endif } Percpu; @@ -88,6 +68,19 @@ STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid) return &g_percpu[cpuid]; } +STATIC INLINE UINT32 OsCpuStatusIsHalt(UINT16 cpuid) +{ + return (OsPercpuGetByID(cpuid)->excFlag == CPU_HALT); +} + +STATIC INLINE VOID OsCpuStatusSet(ExcFlag flag) +{ + OsPercpuGet()->excFlag = flag; +} + +VOID OsAllCpuStatusOutput(VOID); +#endif + #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index a585afae..0403d132 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -374,16 +374,11 @@ STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID) UINT32 intSave; intSave = LOS_IntLock(); - LosProcessCB *runProcess = (LosProcessCB *)OsPercpuGet()->runProcess; + LosProcessCB *runProcess = OS_PCB_FROM_PID(OsCurrTaskGet()->processID); LOS_IntRestore(intSave); return runProcess; } -STATIC INLINE VOID OsCurrProcessSet(const LosProcessCB *process) -{ - OsPercpuGet()->runProcess = (UINTPTR)process; -} - #ifdef LOSCFG_SECURITY_CAPABILITY STATIC INLINE User *OsCurrUserGet(VOID) { @@ -395,8 +390,32 @@ STATIC INLINE User *OsCurrUserGet(VOID) LOS_IntRestore(intSave); return user; } + +STATIC INLINE UINT32 OsProcessUserIDGet(const LosTaskCB *taskCB) +{ + UINT32 intSave = LOS_IntLock(); + UINT32 uid = OS_INVALID; + + LosProcessCB *process = OS_PCB_FROM_PID(taskCB->processID); + if (process->user != NULL) { + uid = process->user->userID; + } + LOS_IntRestore(intSave); + return uid; +} #endif +STATIC INLINE UINT32 OsProcessThreadGroupIDGet(const LosTaskCB *taskCB) +{ + return OS_PCB_FROM_PID(taskCB->processID)->threadGroupID; +} + +#ifdef LOSCFG_DRIVERS_TZDRIVER +STATIC INLINE struct Vnode *OsProcessExecVnodeGet(const LosProcessCB *processCB) +{ + return processCB->execVnode; +} +#endif /* * return immediately if no child has exited. */ diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index 0df3005b..09d49654 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -32,10 +32,8 @@ #ifndef _LOS_SCHED_PRI_H #define _LOS_SCHED_PRI_H -#include "los_percpu_pri.h" #include "los_task_pri.h" #include "los_sys_pri.h" -#include "los_process_pri.h" #include "los_hwi.h" #include "hal_timer.h" @@ -50,7 +48,200 @@ extern "C" { #define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(((UINT64)-1) - 1U) extern UINT32 g_taskScheduled; -typedef BOOL (*SchedScan)(VOID); +#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) +#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK) + +typedef BOOL (*SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR); + +typedef enum { + INT_NO_RESCH = 0x0, /* no needs to schedule */ + INT_PEND_RESCH = 0x1, /* pending schedule flag */ + INT_PEND_TICK = 0x2, /* pending tick */ +} SchedFlag; + +typedef struct { + SortLinkAttribute taskSortLink; /* task sort link */ + SortLinkAttribute swtmrSortLink; /* swtmr 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 swtmrTaskID; /* software timer task id */ + UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ + UINT32 schedFlag; /* pending scheduler flag */ +} SchedRunQue; + +extern SchedRunQue g_schedRunQue[LOSCFG_KERNEL_CORE_NUM]; + +STATIC INLINE SchedRunQue *OsSchedRunQue(VOID) +{ + return &g_schedRunQue[ArchCurrCpuid()]; +} + +STATIC INLINE SchedRunQue *OsSchedRunQueByID(UINT16 id) +{ + return &g_schedRunQue[id]; +} + +STATIC INLINE UINT32 OsSchedLockCountGet(VOID) +{ + return OsSchedRunQue()->taskLockCnt; +} + +STATIC INLINE VOID OsSchedLockSet(UINT32 count) +{ + OsSchedRunQue()->taskLockCnt = count; +} + +STATIC INLINE VOID OsSchedLock(VOID) +{ + OsSchedRunQue()->taskLockCnt++; +} + +STATIC INLINE VOID OsSchedUnlock(VOID) +{ + OsSchedRunQue()->taskLockCnt--; +} + +STATIC INLINE BOOL OsSchedUnlockResch(VOID) +{ + SchedRunQue *rq = OsSchedRunQue(); + if (rq->taskLockCnt > 0) { + rq->taskLockCnt--; + if ((rq->taskLockCnt == 0) && (rq->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { + return TRUE; + } + } + + return FALSE; +} + +STATIC INLINE BOOL OsSchedIsLock(VOID) +{ + return (OsSchedRunQue()->taskLockCnt != 0); +} + +/* Check if preemptable with counter flag */ +STATIC INLINE BOOL OsPreemptable(VOID) +{ + SchedRunQue *rq = OsSchedRunQue(); + /* + * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable + * is called, needs mannually disable interrupt, to prevent current task from + * being migrated to another core, and get the wrong preeptable status. + */ + UINT32 intSave = LOS_IntLock(); + BOOL preemptable = (rq->taskLockCnt == 0); + if (!preemptable) { + /* Set schedule flag if preemption is disabled */ + rq->schedFlag |= INT_PEND_RESCH; + } + LOS_IntRestore(intSave); + return preemptable; +} + +STATIC INLINE BOOL OsPreemptableInSched(VOID) +{ + BOOL preemptable = FALSE; + SchedRunQue *rq = OsSchedRunQue(); + +#ifdef LOSCFG_KERNEL_SMP + /* + * For smp systems, schedule must hold the task spinlock, and this counter + * will increase by 1 in that case. + */ + preemptable = (rq->taskLockCnt == 1); + +#else + preemptable = (rq->taskLockCnt == 0); +#endif + if (!preemptable) { + /* Set schedule flag if preemption is disabled */ + rq->schedFlag |= INT_PEND_RESCH; + } + + return preemptable; +} + +STATIC INLINE UINT32 OsSchedGetRunQueIdle(VOID) +{ + return OsSchedRunQue()->idleTaskID; +} + +STATIC INLINE VOID OsSchedRunQuePendingSet(VOID) +{ + OsSchedRunQue()->schedFlag |= INT_PEND_RESCH; +} + +#ifdef LOSCFG_KERNEL_SMP +STATIC INLINE VOID FindIdleRunQue(UINT16 *idleCpuID) +{ + SchedRunQue *idleRq = OsSchedRunQueByID(0); + UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->taskSortLink) + OsGetSortLinkNodeNum(&idleRq->swtmrSortLink); + UINT16 cpuID = 1; + do { + SchedRunQue *rq = OsSchedRunQueByID(cpuID); + UINT32 temp = OsGetSortLinkNodeNum(&rq->taskSortLink) + OsGetSortLinkNodeNum(&rq->swtmrSortLink); + if (nodeNum > temp) { + *idleCpuID = cpuID; + nodeNum = temp; + } + cpuID++; + } while (cpuID < LOSCFG_KERNEL_CORE_NUM); +} +#endif + +STATIC INLINE VOID OsSchedAddTask2TimeList(SortLinkList *node, UINT64 startTime, UINT32 waitTicks) +{ + UINT16 idleCpu = 0; +#ifdef LOSCFG_KERNEL_SMP + FindIdleRunQue(&idleCpu); +#endif + SchedRunQue *rq = OsSchedRunQueByID(idleCpu); + UINT64 responseTime = startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK; + OsAdd2SortLink(&rq->taskSortLink, node, responseTime, idleCpu); +} + +STATIC INLINE UINT32 OsSchedSwtmrHandlerQueueGet(VOID) +{ + return OsSchedRunQue()->swtmrHandlerQueue; +} + +STATIC INLINE VOID OsSchedDeTaskFromTimeList(SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + SchedRunQue *rq = OsSchedRunQueByID(node->cpuid); +#else + SchedRunQue *rq = OsSchedRunQueByID(0); +#endif + OsDeleteFromSortLink(&rq->taskSortLink, node); +} + +STATIC INLINE VOID OsSchedAddSwtmr2TimeList(SortLinkList *node, UINT64 startTime, UINT32 waitTicks) +{ + UINT16 idleCpu = 0; +#ifdef LOSCFG_KERNEL_SMP + FindIdleRunQue(&idleCpu); +#endif + SchedRunQue *rq = OsSchedRunQueByID(idleCpu); + UINT64 responseTime = startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK; + OsAdd2SortLink(&rq->swtmrSortLink, node, responseTime, idleCpu); +} + +STATIC INLINE VOID OsSchedDeSwtmrFromTimeList(SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + SchedRunQue *rq = OsSchedRunQueByID(node->cpuid); +#else + SchedRunQue *rq = OsSchedRunQueByID(0); +#endif + OsDeleteFromSortLink(&rq->swtmrSortLink, node); +} + +VOID OsSchedRunQueIdleInit(UINT32 idleTaskID); +VOID OsSchedRunQueSwtmrInit(UINT32 swtmrTaskID, UINT32 swtmrQueue); +VOID OsSchedRunQueInit(VOID); +BOOL OsSchedSwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg); STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) { @@ -81,135 +272,46 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID) g_taskScheduled &= ~(1U << (cpuid)); \ } while (0); -#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) -#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK) - -typedef enum { - INT_NO_RESCH = 0x0, /* no needs to schedule */ - INT_PEND_RESCH = 0x1, /* pending schedule flag */ - INT_PEND_TICK = 0x2, /* pending tick */ -} SchedFlag; - -/* Check if preemptable with counter flag */ -STATIC INLINE BOOL OsPreemptable(VOID) -{ - /* - * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable - * is called, needs mannually disable interrupt, to prevent current task from - * being migrated to another core, and get the wrong preeptable status. - */ - UINT32 intSave = LOS_IntLock(); - BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0); - if (!preemptable) { - /* Set schedule flag if preemption is disabled */ - OsPercpuGet()->schedFlag |= INT_PEND_RESCH; - } - LOS_IntRestore(intSave); - return preemptable; -} - -STATIC INLINE BOOL OsPreemptableInSched(VOID) -{ - BOOL preemptable = FALSE; - -#ifdef LOSCFG_KERNEL_SMP - /* - * For smp systems, schedule must hold the task spinlock, and this counter - * will increase by 1 in that case. - */ - preemptable = (OsPercpuGet()->taskLockCnt == 1); - -#else - preemptable = (OsPercpuGet()->taskLockCnt == 0); -#endif - if (!preemptable) { - /* Set schedule flag if preemption is disabled */ - OsPercpuGet()->schedFlag |= INT_PEND_RESCH; - } - - return preemptable; -} - -STATIC INLINE VOID OsCpuSchedLock(Percpu *cpu) -{ - cpu->taskLockCnt++; -} - -STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave) -{ - if (cpu->taskLockCnt > 0) { - cpu->taskLockCnt--; - if ((cpu->taskLockCnt == 0) && (cpu->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { - cpu->schedFlag &= ~INT_PEND_RESCH; - LOS_IntRestore(intSave); - LOS_Schedule(); - return; - } - } - - LOS_IntRestore(intSave); -} - -extern VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask); - -extern UINT32 OsSchedSwtmrScanRegister(SchedScan func); - -extern VOID OsSchedResetSchedResponseTime(UINT64 responseTime); - -extern VOID OsSchedUpdateExpireTime(UINT64 startTime); - -extern VOID OsSchedToUserReleaseLock(VOID); - -extern VOID OsSchedTaskDeQueue(LosTaskCB *taskCB); - -extern VOID OsSchedTaskEnQueue(LosTaskCB *taskCB); - -extern UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched); - -extern VOID OsSchedTaskWake(LosTaskCB *resumedTask); - -extern BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priority); - -extern BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT16 priority); - -extern VOID OsSchedSuspend(LosTaskCB *taskCB); - -extern BOOL OsSchedResume(LosTaskCB *taskCB); - -extern VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick); - -extern VOID OsSchedYield(VOID); - -extern VOID OsSchedTaskExit(LosTaskCB *taskCB); - -extern VOID OsSchedTick(VOID); - -extern UINT32 OsSchedInit(VOID); - -extern VOID OsSchedStart(VOID); +VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask); +VOID OsSchedResetSchedResponseTime(UINT64 responseTime); +VOID OsSchedUpdateExpireTime(VOID); +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, UINT32 tick); +VOID OsSchedYield(VOID); +VOID OsSchedTaskExit(LosTaskCB *taskCB); +VOID OsSchedTick(VOID); +UINT32 OsSchedInit(VOID); +VOID OsSchedStart(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 * queues it needs to be in. */ -extern VOID OsSchedResched(VOID); - -extern VOID OsSchedIrqEndCheckNeedSched(VOID); +VOID OsSchedResched(VOID); +VOID OsSchedIrqEndCheckNeedSched(VOID); /* * This function inserts the runTask to the lock pending list based on the * task priority. */ -extern LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList); +LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList); #ifdef LOSCFG_SCHED_TICK_DEBUG -extern VOID OsSchedDebugRecordData(VOID); +VOID OsSchedDebugRecordData(VOID); #endif -extern UINT32 OsShellShowTickRespo(VOID); +UINT32 OsShellShowTickRespo(VOID); -extern UINT32 OsShellShowSchedParam(VOID); +UINT32 OsShellShowSchedParam(VOID); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h index caa344c5..83465653 100644 --- a/kernel/base/include/los_sortlink_pri.h +++ b/kernel/base/include/los_sortlink_pri.h @@ -34,7 +34,7 @@ #include "los_typedef.h" #include "los_list.h" -#include "los_sys_pri.h" +#include "los_spinlock.h" #ifdef __cplusplus #if __cplusplus @@ -42,11 +42,6 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -typedef enum { - OS_SORT_LINK_TASK = 1, - OS_SORT_LINK_SWTMR = 2, -} SortLinkType; - typedef struct { LOS_DL_LIST sortLinkNode; UINT64 responseTime; @@ -58,6 +53,7 @@ typedef struct { typedef struct { LOS_DL_LIST sortLink; UINT32 nodeNum; + SPIN_LOCK_S spinLock; /* swtmr sort link spin lock */ } SortLinkAttribute; #define OS_SORT_LINK_INVALID_TIME ((UINT64)-1) @@ -88,11 +84,16 @@ STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, return listSorted->responseTime; } -extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader); -extern VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type); -extern VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type); -extern UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList); -extern UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader); +STATIC INLINE UINT32 OsGetSortLinkNodeNum(SortLinkAttribute *head) +{ + return head->nodeNum; +} + +VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader); +VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu); +VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node); +UINT32 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList); +UINT32 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_swtmr_pri.h b/kernel/base/include/los_swtmr_pri.h index 31651f89..b41f6840 100644 --- a/kernel/base/include/los_swtmr_pri.h +++ b/kernel/base/include/los_swtmr_pri.h @@ -34,6 +34,7 @@ #include "los_swtmr.h" #include "los_spinlock.h" +#include "los_sched_pri.h" #ifdef LOSCFG_SECURITY_VID #include "vid_api.h" @@ -75,8 +76,6 @@ typedef SwtmrHandlerItem *SwtmrHandlerItemPtr; extern SWTMR_CTRL_S *g_swtmrCBArray; -extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */ - #define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT)) /** @@ -100,11 +99,13 @@ extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */ * * @see LOS_SwtmrStop */ -extern VOID OsSwtmrScan(VOID); + +extern BOOL OsIsSwtmrTask(const LosTaskCB *taskCB); +extern VOID OsSwtmrRestart(UINT64 startTime, SortLinkList *sortList); +extern VOID OsSwtmrWake(SchedRunQue *rq, UINT64 currTime, SortLinkList *sortList); extern UINT32 OsSwtmrInit(VOID); -extern VOID OsSwtmrTask(VOID); extern VOID OsSwtmrRecycle(UINT32 processID); -extern VOID OsSwtmrResponseTimeReset(UINT64 startTime); +extern BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg); extern SPIN_LOCK_S g_swtmrSpin; #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index 04c5454f..f9030500 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -33,7 +33,7 @@ #define _LOS_TASK_PRI_H #include "los_task.h" -#include "los_percpu_pri.h" +#include "los_sortlink_pri.h" #include "los_spinlock.h" #ifdef LOSCFG_SCHED_DEBUG #include "los_stat_pri.h" @@ -528,7 +528,6 @@ extern LosTaskCB *OsGetMainTask(VOID); extern VOID OsSetMainTask(VOID); extern UINT32 OsGetIdleTaskId(VOID); extern VOID OsTaskEntry(UINT32 taskID); -extern SortLinkAttribute *OsTaskSortLinkGet(VOID); extern VOID OsTaskProcSignal(VOID); extern UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave); extern VOID OsTaskResourcesToFree(LosTaskCB *taskCB); diff --git a/kernel/base/ipc/los_futex.c b/kernel/base/ipc/los_futex.c index b1381779..589e0ef8 100644 --- a/kernel/base/ipc/los_futex.c +++ b/kernel/base/ipc/los_futex.c @@ -602,18 +602,18 @@ 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); - OsPercpuGet()->taskLockCnt++; + OsSchedLock(); LOS_SpinUnlock(&g_taskSpin); futexRet = OsFutexUnlock(&hashNode->listLock); if (futexRet) { - OsPercpuGet()->taskLockCnt--; + OsSchedUnlock(); LOS_IntRestore(intSave); goto EXIT_UNLOCK_ERR; } LOS_SpinLock(&g_taskSpin); - OsPercpuGet()->taskLockCnt--; + OsSchedUnlock(); /* * it will immediately do the scheduling, so there's no need to release the diff --git a/kernel/base/mp/los_mp.c b/kernel/base/mp/los_mp.c index dbbf9415..c4e9b183 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. */ - OsPercpuGet()->schedFlag |= INT_PEND_RESCH; + OsSchedRunQuePendingSet(); } VOID OsMpHaltHandler(VOID) diff --git a/kernel/base/mp/los_percpu.c b/kernel/base/mp/los_percpu.c index c50e31e9..4d883916 100644 --- a/kernel/base/mp/los_percpu.c +++ b/kernel/base/mp/los_percpu.c @@ -30,7 +30,30 @@ */ #include "los_percpu_pri.h" +#include "los_printf.h" - +#ifdef LOSCFG_KERNEL_SMP Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; +VOID OsAllCpuStatusOutput(VOID) +{ + UINT32 i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + switch (g_percpu[i].excFlag) { + case CPU_RUNNING: + PrintExcInfo("cpu%u is running.\n", i); + break; + case CPU_HALT: + PrintExcInfo("cpu%u is halted.\n", i); + break; + case CPU_EXC: + PrintExcInfo("cpu%u is in exc.\n", i); + break; + default: + break; + } + } + PrintExcInfo("The current handling the exception is cpu%u !\n", ArchCurrCpuid()); +} +#endif diff --git a/kernel/base/mp/los_spinlock.c b/kernel/base/mp/los_spinlock.c index 991af71d..63d7fb50 100644 --- a/kernel/base/mp/los_spinlock.c +++ b/kernel/base/mp/los_spinlock.c @@ -50,7 +50,7 @@ BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) VOID LOS_SpinLock(SPIN_LOCK_S *lock) { UINT32 intSave = LOS_IntLock(); - OsCpuSchedLock(OsPercpuGet()); + OsSchedLock(); LOS_IntRestore(intSave); LOCKDEP_CHECK_IN(lock); @@ -60,17 +60,22 @@ VOID LOS_SpinLock(SPIN_LOCK_S *lock) INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) { - Percpu *cpu = OsPercpuGet(); UINT32 intSave = LOS_IntLock(); - OsCpuSchedLock(cpu); + OsSchedLock(); LOS_IntRestore(intSave); INT32 ret = ArchSpinTrylock(&lock->rawLock); if (ret == LOS_OK) { LOCKDEP_CHECK_IN(lock); LOCKDEP_RECORD(lock); - } else { - OsCpuSchedUnlock(cpu, LOS_IntLock()); + return ret; + } + + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); } return ret; @@ -78,16 +83,22 @@ INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) { + UINT32 intSave; LOCKDEP_CHECK_OUT(lock); ArchSpinUnlock(&lock->rawLock); - OsCpuSchedUnlock(OsPercpuGet(), LOS_IntLock()); + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); + } } VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) { *intSave = LOS_IntLock(); - OsCpuSchedLock(OsPercpuGet()); + OsSchedLock(); LOCKDEP_CHECK_IN(lock); ArchSpinLock(&lock->rawLock); @@ -99,7 +110,11 @@ VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) LOCKDEP_CHECK_OUT(lock); ArchSpinUnlock(&lock->rawLock); - OsCpuSchedUnlock(OsPercpuGet(), intSave); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); + } } #endif diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c index edc85900..d0fb5660 100644 --- a/kernel/base/sched/sched_sq/los_sched.c +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -71,11 +71,10 @@ typedef struct { typedef struct { SchedQueue queueList[OS_PRIORITY_QUEUE_NUM]; UINT32 queueBitmap; - SchedScan taskScan; - SchedScan swtmrScan; } Sched; -STATIC Sched *g_sched = NULL; +SchedRunQue g_schedRunQue[LOSCFG_KERNEL_CORE_NUM]; +STATIC Sched g_sched; #ifdef LOSCFG_SCHED_TICK_DEBUG #define OS_SCHED_DEBUG_DATA_NUM 1000 @@ -132,7 +131,8 @@ UINT32 OsShellShowTickRespo(VOID) (VOID)memcpy_s((CHAR *)schedDebug, tickSize, (CHAR *)OsSchedDebugGet(), tickSize); (VOID)memset_s((CHAR *)OsSchedDebugGet(), tickSize, 0, tickSize); for (cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { - sortLinkNum[cpu] = OsPercpuGetByID(cpu)->taskSortLink.nodeNum + OsPercpuGetByID(cpu)->swtmrSortLink.nodeNum; + SchedRunQue *rq = OsSchedRunQueByID(cpu); + sortLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->taskSortLink) + OsGetSortLinkNodeNum(&rq->swtmrSortLink); } SCHEDULER_UNLOCK(intSave); @@ -236,7 +236,7 @@ UINT32 OsShellShowSchedParam(VOID) } #endif -STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) +STATIC INLINE VOID TimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) { LOS_ASSERT(currTime >= taskCB->startTime); @@ -258,34 +258,33 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) #endif } -STATIC INLINE UINT64 GetNextExpireTime(Percpu *cpu, UINT64 startTime, UINT32 tickPrecision) +STATIC INLINE UINT64 GetNextExpireTime(SchedRunQue *rq, UINT64 startTime, UINT32 tickPrecision) { - SortLinkAttribute *taskHeader = &cpu->taskSortLink; - SortLinkAttribute *swtmrHeader = &cpu->swtmrSortLink; + SortLinkAttribute *taskHeader = &rq->taskSortLink; + SortLinkAttribute *swtmrHeader = &rq->swtmrSortLink; - LOS_SpinLock(&cpu->taskSortLinkSpin); + LOS_SpinLock(&taskHeader->spinLock); UINT64 taskExpireTime = OsGetSortLinkNextExpireTime(taskHeader, startTime, tickPrecision); - LOS_SpinUnlock(&cpu->taskSortLinkSpin); + LOS_SpinUnlock(&taskHeader->spinLock); - LOS_SpinLock(&cpu->swtmrSortLinkSpin); + LOS_SpinLock(&swtmrHeader->spinLock); UINT64 swtmrExpireTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime, tickPrecision); - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); + LOS_SpinUnlock(&swtmrHeader->spinLock); return (taskExpireTime < swtmrExpireTime) ? taskExpireTime : swtmrExpireTime; } -STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, - UINT64 taskEndTime, UINT32 oldResponseID) +STATIC INLINE VOID SchedSetNextExpireTime(UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) { - Percpu *currCpu = OsPercpuGet(); - UINT64 nextResponseTime = 0; + SchedRunQue *rq = OsSchedRunQue(); BOOL isTimeSlice = FALSE; - UINT64 nextExpireTime = GetNextExpireTime(currCpu, startTime, OS_TICK_RESPONSE_PRECISION); + UINT64 currTime = OsGetCurrSchedTimeCycle(); + UINT64 nextExpireTime = GetNextExpireTime(rq, currTime, OS_TICK_RESPONSE_PRECISION); - currCpu->schedFlag &= ~INT_PEND_TICK; - if (currCpu->responseID == oldResponseID) { + rq->schedFlag &= ~INT_PEND_TICK; + if (rq->responseID == oldResponseID) { /* This time has expired, and the next time the theory has expired is infinite */ - currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; } /* The current thread's time slice has been consumed, but the current system lock task cannot @@ -296,28 +295,20 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, isTimeSlice = TRUE; } - if ((currCpu->responseTime <= nextExpireTime) || - ((currCpu->responseTime - nextExpireTime) < OS_TICK_RESPONSE_PRECISION)) { + if ((rq->responseTime <= nextExpireTime) || + ((rq->responseTime - nextExpireTime) < OS_TICK_RESPONSE_PRECISION)) { return; } - UINT64 currTime = OsGetCurrSchedTimeCycle(); - if (nextExpireTime >= currTime) { - nextResponseTime = nextExpireTime - currTime; - } - - if (nextResponseTime < OS_TICK_RESPONSE_PRECISION) { - nextResponseTime = OS_TICK_RESPONSE_PRECISION; - } - if (isTimeSlice) { /* The expiration time of the current system is the thread's slice expiration time */ - currCpu->responseID = responseID; + rq->responseID = responseID; } else { - currCpu->responseID = OS_INVALID_VALUE; + rq->responseID = OS_INVALID_VALUE; } - currCpu->responseTime = currTime + HalClockTickTimerReload(nextResponseTime); + UINT64 nextResponseTime = nextExpireTime - currTime; + rq->responseTime = currTime + HalClockTickTimerReload(nextResponseTime); #ifdef LOSCFG_SCHED_TICK_DEBUG SchedTickDebug *schedDebug = &g_schedTickDebug[ArchCurrCpuid()]; @@ -327,35 +318,34 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, #endif } -VOID OsSchedUpdateExpireTime(UINT64 startTime) +VOID OsSchedUpdateExpireTime(VOID) { UINT64 endTime; - Percpu *cpu = OsPercpuGet(); LosTaskCB *runTask = OsCurrTaskGet(); if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) { - cpu->schedFlag |= INT_PEND_TICK; + OsSchedRunQuePendingSet(); 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); - endTime = startTime + timeSlice; } else { endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; } - OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, runTask->taskID); + SchedSetNextExpireTime(runTask->taskID, endTime, runTask->taskID); } -STATIC INLINE UINT32 OsSchedCalculateTimeSlice(UINT16 proPriority, UINT16 priority) +STATIC INLINE UINT32 SchedCalculateTimeSlice(UINT16 proPriority, UINT16 priority) { UINT32 retTime; UINT32 readyTasks; - SchedQueue *queueList = &g_sched->queueList[proPriority]; + SchedQueue *queueList = &g_sched.queueList[proPriority]; readyTasks = queueList->readyTasks[priority]; if (readyTasks > OS_SCHED_READY_MAX) { return OS_SCHED_TIME_SLICES_MIN; @@ -364,9 +354,9 @@ STATIC INLINE UINT32 OsSchedCalculateTimeSlice(UINT16 proPriority, UINT16 priori return (retTime + OS_SCHED_TIME_SLICES_MIN); } -STATIC INLINE VOID OsSchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) +STATIC INLINE VOID SchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) { - SchedQueue *queueList = &g_sched->queueList[proPriority]; + SchedQueue *queueList = &g_sched.queueList[proPriority]; LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; UINT32 *bitMap = &queueList->queueBitmap; @@ -378,7 +368,7 @@ STATIC INLINE VOID OsSchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *prique LOS_ASSERT(priqueueItem->pstNext == NULL); if (*bitMap == 0) { - g_sched->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; + g_sched.queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; } if (LOS_ListEmpty(&priQueueList[priority])) { @@ -389,9 +379,9 @@ STATIC INLINE VOID OsSchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *prique queueList->readyTasks[priority]++; } -STATIC INLINE VOID OsSchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) +STATIC INLINE VOID SchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) { - SchedQueue *queueList = &g_sched->queueList[proPriority]; + SchedQueue *queueList = &g_sched.queueList[proPriority]; LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; UINT32 *bitMap = &queueList->queueBitmap; @@ -403,7 +393,7 @@ STATIC INLINE VOID OsSchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *prique LOS_ASSERT(priqueueItem->pstNext == NULL); if (*bitMap == 0) { - g_sched->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; + g_sched.queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; } if (LOS_ListEmpty(&priQueueList[priority])) { @@ -414,9 +404,9 @@ STATIC INLINE VOID OsSchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *prique queueList->readyTasks[priority]++; } -STATIC INLINE VOID OsSchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) +STATIC INLINE VOID SchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) { - SchedQueue *queueList = &g_sched->queueList[proPriority]; + SchedQueue *queueList = &g_sched.queueList[proPriority]; LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; UINT32 *bitMap = &queueList->queueBitmap; @@ -427,95 +417,22 @@ STATIC INLINE VOID OsSchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *prique } if (*bitMap == 0) { - g_sched->queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> proPriority); + g_sched.queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> proPriority); } } -STATIC INLINE VOID OsSchedWakePendTimeTask(UINT64 currTime, LosTaskCB *taskCB, BOOL *needSchedule) -{ -#ifndef LOSCFG_SCHED_DEBUG - (VOID)currTime; -#endif - - LOS_SpinLock(&g_taskSpin); - UINT16 tempStatus = taskCB->taskStatus; - if (tempStatus & (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) { - taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY); - if (tempStatus & OS_TASK_STATUS_PENDING) { - taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT; - LOS_ListDelete(&taskCB->pendList); - taskCB->taskMux = NULL; - OsTaskWakeClearPendMask(taskCB); - } - - if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) { -#ifdef LOSCFG_SCHED_DEBUG - taskCB->schedStat.pendTime += currTime - taskCB->startTime; - taskCB->schedStat.pendCount++; -#endif - OsSchedTaskEnQueue(taskCB); - *needSchedule = TRUE; - } - } - - LOS_SpinUnlock(&g_taskSpin); -} - -STATIC INLINE BOOL OsSchedScanTimerList(VOID) -{ - Percpu *cpu = OsPercpuGet(); - BOOL needSchedule = FALSE; - SortLinkAttribute *taskSortLink = &OsPercpuGet()->taskSortLink; - LOS_DL_LIST *listObject = &taskSortLink->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 - * up by either timeout or corresponding ipc it's waiting. - * - * 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(&cpu->taskSortLinkSpin); - - if (LOS_ListEmpty(listObject)) { - LOS_SpinUnlock(&cpu->taskSortLinkSpin); - return needSchedule; - } - - 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(&cpu->taskSortLinkSpin); - - OsSchedWakePendTimeTask(currTime, taskCB, &needSchedule); - - LOS_SpinLock(&cpu->taskSortLinkSpin); - if (LOS_ListEmpty(listObject)) { - break; - } - - sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); - } - - LOS_SpinUnlock(&cpu->taskSortLinkSpin); - - return needSchedule; -} - -STATIC INLINE VOID OsSchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) +STATIC INLINE VOID SchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) { LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); switch (taskCB->policy) { case LOS_SCHED_RR: { if (taskCB->timeSlice > OS_TIME_SLICE_MIN) { - OsSchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority); } else { - taskCB->initTimeSlice = OsSchedCalculateTimeSlice(processCB->priority, taskCB->priority); + taskCB->initTimeSlice = SchedCalculateTimeSlice(processCB->priority, taskCB->priority); taskCB->timeSlice = taskCB->initTimeSlice; - OsSchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); #ifdef LOSCFG_SCHED_DEBUG taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime; taskCB->schedStat.timeSliceCount++; @@ -526,11 +443,11 @@ STATIC INLINE VOID OsSchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB 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)) { - OsSchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority); } else { taskCB->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; taskCB->timeSlice = taskCB->initTimeSlice; - OsSchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); } break; } @@ -552,10 +469,10 @@ STATIC INLINE VOID OsSchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB processCB->readyTaskNum++; } -STATIC INLINE VOID OsSchedDeTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) +STATIC INLINE VOID SchedDeTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) { if (taskCB->policy != LOS_SCHED_IDLE) { - OsSchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority); } taskCB->taskStatus &= ~OS_TASK_STATUS_READY; @@ -570,7 +487,7 @@ VOID OsSchedTaskDeQueue(LosTaskCB *taskCB) LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - OsSchedDeTaskQueue(taskCB, processCB); + SchedDeTaskQueue(taskCB, processCB); } if (processCB->processStatus & OS_PROCESS_STATUS_READY) { @@ -593,7 +510,7 @@ VOID OsSchedTaskEnQueue(LosTaskCB *taskCB) taskCB->startTime = OsGetCurrSchedTimeCycle(); } #endif - OsSchedEnTaskQueue(taskCB, processCB); + SchedEnTaskQueue(taskCB, processCB); } VOID OsSchedTaskExit(LosTaskCB *taskCB) @@ -609,7 +526,7 @@ VOID OsSchedTaskExit(LosTaskCB *taskCB) } if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { - OsDeleteSortLink(&taskCB->sortList, OS_SORT_LINK_TASK); + OsSchedDeTaskFromTimeList(&taskCB->sortList); taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); } } @@ -664,7 +581,7 @@ VOID OsSchedTaskWake(LosTaskCB *resumedTask) resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { - OsDeleteSortLink(&resumedTask->sortList, OS_SORT_LINK_TASK); + OsSchedDeTaskFromTimeList(&resumedTask->sortList); resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; } @@ -705,8 +622,9 @@ BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priori return FALSE; } -BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT16 priority) +BOOL OsSchedModifyProcessSchedParam(UINT32 pid, UINT16 policy, UINT16 priority) { + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); LosTaskCB *taskCB = NULL; BOOL needSched = FALSE; (VOID)policy; @@ -714,8 +632,8 @@ BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT if (processCB->processStatus & OS_PROCESS_STATUS_READY) { LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - OsSchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority); - OsSchedPriQueueEnTail(priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(priority, &taskCB->pendList, taskCB->priority); needSched = TRUE; } } @@ -729,7 +647,7 @@ BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT return needSched; } -STATIC VOID OsSchedFreezeTask(LosTaskCB *taskCB) +STATIC VOID SchedFreezeTask(LosTaskCB *taskCB) { UINT64 responseTime; @@ -742,13 +660,13 @@ STATIC VOID OsSchedFreezeTask(LosTaskCB *taskCB) } responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); - OsDeleteSortLink(&taskCB->sortList, OS_SORT_LINK_TASK); + OsSchedDeTaskFromTimeList(&taskCB->sortList); SET_SORTLIST_VALUE(&taskCB->sortList, responseTime); taskCB->taskStatus |= OS_TASK_FLAG_FREEZE; return; } -STATIC VOID OsSchedUnfreezeTask(LosTaskCB *taskCB) +STATIC VOID SchedUnfreezeTask(LosTaskCB *taskCB) { UINT64 currTime, responseTime; UINT32 remainTick; @@ -762,7 +680,7 @@ STATIC VOID OsSchedUnfreezeTask(LosTaskCB *taskCB) responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); if (responseTime > currTime) { remainTick = ((responseTime - currTime) + OS_CYCLE_PER_TICK - 1) / OS_CYCLE_PER_TICK; - OsAdd2SortLink(&taskCB->sortList, currTime, remainTick, OS_SORT_LINK_TASK); + OsSchedAddTask2TimeList(&taskCB->sortList, currTime, remainTick); return; } @@ -780,7 +698,7 @@ VOID OsSchedSuspend(LosTaskCB *taskCB) OsSchedTaskDeQueue(taskCB); } - OsSchedFreezeTask(taskCB); + SchedFreezeTask(taskCB); taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED; OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB); @@ -793,7 +711,7 @@ BOOL OsSchedResume(LosTaskCB *taskCB) { BOOL needSched = FALSE; - OsSchedUnfreezeTask(taskCB); + SchedUnfreezeTask(taskCB); taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) { @@ -804,26 +722,184 @@ BOOL OsSchedResume(LosTaskCB *taskCB) return needSched; } -VOID OsSchedTick(VOID) +STATIC INLINE BOOL SchedScanSwtmrTimeList(SchedRunQue *rq) { - Sched *sched = g_sched; - Percpu *currCpu = OsPercpuGet(); BOOL needSched = FALSE; + SortLinkAttribute* swtmrSortLink = &rq->swtmrSortLink; + LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; - if (currCpu->responseID == OS_INVALID_VALUE) { - if (sched->swtmrScan != NULL) { - (VOID)sched->swtmrScan(); + /* + * it needs to be carefully coped with, since the swtmr is in specific sortlink + * while other cores still has the chance to process it, like stop the timer. + */ + LOS_SpinLock(&swtmrSortLink->spinLock); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return FALSE; + } + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + + UINT64 currTime = OsGetCurrSchedTimeCycle(); + while (sortList->responseTime <= currTime) { + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + UINT64 startTime = GET_SORTLIST_VALUE(sortList); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlock(&swtmrSortLink->spinLock); + + OsSwtmrWake(rq, startTime, sortList); + needSched = TRUE; + + LOS_SpinLock(&swtmrSortLink->spinLock); + if (LOS_ListEmpty(listObject)) { + break; } - needSched = sched->taskScan(); + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + } + + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return needSched; +} + +STATIC INLINE VOID SchedSwtmrResponseTimeReset(SchedRunQue *rq, UINT64 startTime) +{ + SortLinkAttribute* swtmrSortLink = &rq->swtmrSortLink; + LOS_DL_LIST *listHead = &swtmrSortLink->sortLink; + LOS_DL_LIST *listNext = listHead->pstNext; + + LOS_SpinLock(&swtmrSortLink->spinLock); + while (listNext != listHead) { + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listNext, SortLinkList, sortLinkNode); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlock(&swtmrSortLink->spinLock); + + OsSwtmrRestart(startTime, sortList); + + LOS_SpinLock(&swtmrSortLink->spinLock); + listNext = listNext->pstNext; + } + LOS_SpinUnlock(&swtmrSortLink->spinLock); +} + +STATIC INLINE BOOL SchedSwtmrRunQueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +{ + LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; + LOS_DL_LIST *list = listObject->pstNext; + + LOS_SpinLock(&swtmrSortLink->spinLock); + while (list != listObject) { + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); + if (checkFunc((UINTPTR)listSorted, arg)) { + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return TRUE; + } + list = list->pstNext; + } + + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return FALSE; +} + +BOOL OsSchedSwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +{ + for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + SchedRunQue *rq = OsSchedRunQueByID(cpuid); + SortLinkAttribute *swtmrSortLink = &rq->swtmrSortLink; + return SchedSwtmrRunQueFind(swtmrSortLink, checkFunc, arg); + } + return FALSE; +} + +STATIC INLINE VOID SchedWakePendTimeTask(UINT64 currTime, LosTaskCB *taskCB, BOOL *needSchedule) +{ +#ifndef LOSCFG_SCHED_DEBUG + (VOID)currTime; +#endif + + LOS_SpinLock(&g_taskSpin); + UINT16 tempStatus = taskCB->taskStatus; + if (tempStatus & (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) { + taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY); + if (tempStatus & OS_TASK_STATUS_PENDING) { + taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT; + LOS_ListDelete(&taskCB->pendList); + taskCB->taskMux = NULL; + OsTaskWakeClearPendMask(taskCB); + } + + if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_DEBUG + taskCB->schedStat.pendTime += currTime - taskCB->startTime; + taskCB->schedStat.pendCount++; +#endif + OsSchedTaskEnQueue(taskCB); + *needSchedule = TRUE; + } + } + + LOS_SpinUnlock(&g_taskSpin); +} + +STATIC INLINE BOOL SchedScanTaskTimeList(SchedRunQue *rq) +{ + BOOL needSchedule = FALSE; + SortLinkAttribute *taskSortLink = &rq->taskSortLink; + LOS_DL_LIST *listObject = &taskSortLink->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 + * up by either timeout or corresponding ipc it's waiting. + * + * 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); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlock(&taskSortLink->spinLock); + return needSchedule; + } + + 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); + + SchedWakePendTimeTask(currTime, taskCB, &needSchedule); + + LOS_SpinLock(&taskSortLink->spinLock); + if (LOS_ListEmpty(listObject)) { + break; + } + + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + } + + LOS_SpinUnlock(&taskSortLink->spinLock); + + return needSchedule; +} + +VOID OsSchedTick(VOID) +{ + SchedRunQue *rq = OsSchedRunQue(); + BOOL needSched = FALSE; + + if (rq->responseID == OS_INVALID_VALUE) { + + needSched |= SchedScanSwtmrTimeList(rq); + needSched |= SchedScanTaskTimeList(rq); if (needSched) { LOS_MpSchedule(OS_MP_CPU_ALL); - currCpu->schedFlag |= INT_PEND_RESCH; + rq->schedFlag |= INT_PEND_RESCH; } } - currCpu->schedFlag |= INT_PEND_TICK; - currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + rq->schedFlag |= INT_PEND_TICK; + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; } VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask) @@ -836,55 +912,48 @@ VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask) VOID OsSchedResetSchedResponseTime(UINT64 responseTime) { - Percpu *cpu = OsPercpuGet(); - cpu->responseTime = responseTime; + OsSchedRunQue()->responseTime = responseTime; } -UINT32 OsSchedSwtmrScanRegister(SchedScan func) +VOID OsSchedRunQueInit(VOID) { - if (func == NULL) { - return LOS_NOK; + if (ArchCurrCpuid() != 0) { + return; } - g_sched->swtmrScan = func; - return LOS_OK; + for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + SchedRunQue *rq = OsSchedRunQueByID(index); + OsSortLinkInit(&rq->taskSortLink); + OsSortLinkInit(&rq->swtmrSortLink); + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + } +} + +VOID OsSchedRunQueSwtmrInit(UINT32 swtmrTaskID, UINT32 swtmrQueue) +{ + SchedRunQue *rq = OsSchedRunQue(); + rq->swtmrTaskID = swtmrTaskID; + rq->swtmrHandlerQueue = swtmrQueue; +} + +VOID OsSchedRunQueIdleInit(UINT32 idleTaskID) +{ + SchedRunQue *rq = OsSchedRunQue(); + rq->idleTaskID = idleTaskID; } UINT32 OsSchedInit(VOID) { - UINT16 index, pri; - UINT32 ret; - - g_sched = (Sched *)LOS_MemAlloc(m_aucSysMem0, sizeof(Sched)); - if (g_sched == NULL) { - return LOS_ERRNO_TSK_NO_MEMORY; - } - - (VOID)memset_s(g_sched, sizeof(Sched), 0, sizeof(Sched)); - - for (index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) { - SchedQueue *queueList = &g_sched->queueList[index]; + for (UINT16 index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) { + SchedQueue *queueList = &g_sched.queueList[index]; LOS_DL_LIST *priList = &queueList->priQueueList[0]; - for (pri = 0; pri < OS_PRIORITY_QUEUE_NUM; pri++) { + for (UINT16 pri = 0; pri < OS_PRIORITY_QUEUE_NUM; pri++) { LOS_ListInit(&priList[pri]); } } - for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { - Percpu *cpu = OsPercpuGetByID(index); - ret = OsSortLinkInit(&cpu->taskSortLink); - if (ret != LOS_OK) { - return LOS_ERRNO_TSK_NO_MEMORY; - } - cpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; - LOS_SpinInit(&cpu->taskSortLinkSpin); - LOS_SpinInit(&cpu->swtmrSortLinkSpin); - } - - g_sched->taskScan = OsSchedScanTimerList; - #ifdef LOSCFG_SCHED_TICK_DEBUG - ret = OsSchedDebugInit(); + UINT32 ret = OsSchedDebugInit(); if (ret != LOS_OK) { return ret; } @@ -892,19 +961,19 @@ UINT32 OsSchedInit(VOID) return LOS_OK; } -STATIC LosTaskCB *OsGetTopTask(VOID) +STATIC LosTaskCB *GetTopTask(SchedRunQue *rq) { UINT32 priority, processPriority; UINT32 bitmap; LosTaskCB *newTask = NULL; - UINT32 processBitmap = g_sched->queueBitmap; + UINT32 processBitmap = g_sched.queueBitmap; #ifdef LOSCFG_KERNEL_SMP UINT32 cpuid = ArchCurrCpuid(); #endif while (processBitmap) { processPriority = CLZ(processBitmap); - SchedQueue *queueList = &g_sched->queueList[processPriority]; + SchedQueue *queueList = &g_sched.queueList[processPriority]; bitmap = queueList->queueBitmap; while (bitmap) { priority = CLZ(bitmap); @@ -922,10 +991,10 @@ STATIC LosTaskCB *OsGetTopTask(VOID) processBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - processPriority - 1)); } - newTask = OS_TCB_FROM_TID(OsPercpuGet()->idleTaskID); + newTask = OS_TCB_FROM_TID(rq->idleTaskID); FIND_TASK: - OsSchedDeTaskQueue(newTask, OS_PCB_FROM_PID(newTask->processID)); + SchedDeTaskQueue(newTask, OS_PCB_FROM_PID(newTask->processID)); return newTask; } @@ -942,7 +1011,8 @@ VOID OsSchedStart(VOID) OsTickStart(); } - LosTaskCB *newTask = OsGetTopTask(); + SchedRunQue *rq = OsSchedRunQue(); + LosTaskCB *newTask = GetTopTask(rq); LosProcessCB *newProcess = OS_PCB_FROM_PID(newTask->processID); newTask->taskStatus |= OS_TASK_STATUS_RUNNING; @@ -961,13 +1031,13 @@ VOID OsSchedStart(VOID) newTask->startTime = OsGetCurrSchedTimeCycle(); - OsSwtmrResponseTimeReset(newTask->startTime); + SchedSwtmrResponseTimeReset(rq, newTask->startTime); /* System start schedule */ OS_SCHEDULER_SET(cpuid); - OsPercpuGet()->responseID = OS_INVALID; - OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, newTask->startTime + newTask->timeSlice, OS_INVALID); + rq->responseID = OS_INVALID; + SchedSetNextExpireTime(newTask->taskID, newTask->startTime + newTask->timeSlice, OS_INVALID); OsTaskContextLoad(newTask); } @@ -978,12 +1048,12 @@ VOID OsSchedToUserReleaseLock(VOID) LOCKDEP_CHECK_OUT(&g_taskSpin); ArchSpinUnlock(&g_taskSpin.rawLock); - OsPercpuGet()->taskLockCnt--; + OsSchedUnlock(); } #endif #ifdef LOSCFG_BASE_CORE_TSK_MONITOR -STATIC VOID OsTaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask) +STATIC VOID TaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask) { if (!OS_STACK_MAGIC_CHECK(runTask->topOfStack)) { LOS_Panic("CURRENT task ID: %s:%d stack overflow!\n", runTask->taskName, runTask->taskID); @@ -997,10 +1067,10 @@ STATIC VOID OsTaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask) } #endif -STATIC INLINE VOID OsSchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) +STATIC INLINE VOID SchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) { #ifdef LOSCFG_BASE_CORE_TSK_MONITOR - OsTaskStackCheck(runTask, newTask); + TaskStackCheck(runTask, newTask); #endif /* LOSCFG_BASE_CORE_TSK_MONITOR */ OsHookCall(LOS_HOOK_TYPE_TASK_SWITCHEDIN, newTask, runTask); } @@ -1023,15 +1093,13 @@ STATIC INLINE VOID OsSchedSwitchProcess(LosProcessCB *runProcess, LosProcessCB * LOS_ArchMmuContextSwitch(&newProcess->vmSpace->archMmu); } #endif - - OsCurrProcessSet(newProcess); } -STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) +STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) { UINT64 endTime; - OsSchedSwitchCheck(runTask, newTask); + SchedSwitchCheck(runTask, newTask); runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING; newTask->taskStatus |= OS_TASK_STATUS_RUNNING; @@ -1067,10 +1135,10 @@ STATIC VOID OsSchedTaskSwitch(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 */ - OsTimeSliceUpdate(runTask, newTask->startTime); + TimeSliceUpdate(runTask, newTask->startTime); if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) { - OsAdd2SortLink(&runTask->sortList, runTask->startTime, runTask->waitTimes, OS_SORT_LINK_TASK); + OsSchedAddTask2TimeList(&runTask->sortList, runTask->startTime, runTask->waitTimes); } } @@ -1079,7 +1147,7 @@ STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) } else { endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; } - OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, endTime, runTask->taskID); + SchedSetNextExpireTime(newTask->taskID, endTime, runTask->taskID); #ifdef LOSCFG_SCHED_DEBUG newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime; @@ -1093,24 +1161,24 @@ STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) VOID OsSchedIrqEndCheckNeedSched(VOID) { - Percpu *percpu = OsPercpuGet(); + SchedRunQue *rq = OsSchedRunQue(); LosTaskCB *runTask = OsCurrTaskGet(); - OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); + TimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); if (runTask->timeSlice <= OS_TIME_SLICE_MIN) { - percpu->schedFlag |= INT_PEND_RESCH; + rq->schedFlag |= INT_PEND_RESCH; } - if (OsPreemptable() && (percpu->schedFlag & INT_PEND_RESCH)) { - percpu->schedFlag &= ~INT_PEND_RESCH; + if (OsPreemptable() && (rq->schedFlag & INT_PEND_RESCH)) { + rq->schedFlag &= ~INT_PEND_RESCH; LOS_SpinLock(&g_taskSpin); OsSchedTaskEnQueue(runTask); - LosTaskCB *newTask = OsGetTopTask(); + LosTaskCB *newTask = GetTopTask(rq); if (runTask != newTask) { - OsSchedTaskSwitch(runTask, newTask); + SchedTaskSwitch(runTask, newTask); LOS_SpinUnlock(&g_taskSpin); return; } @@ -1118,28 +1186,29 @@ VOID OsSchedIrqEndCheckNeedSched(VOID) LOS_SpinUnlock(&g_taskSpin); } - if (percpu->schedFlag & INT_PEND_TICK) { - OsSchedUpdateExpireTime(runTask->startTime); + if (rq->schedFlag & INT_PEND_TICK) { + OsSchedUpdateExpireTime(); } } VOID OsSchedResched(VOID) { LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + SchedRunQue *rq = OsSchedRunQue(); #ifdef LOSCFG_KERNEL_SMP - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 1); + LOS_ASSERT(rq->taskLockCnt == 1); #else - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0); + LOS_ASSERT(rq->taskLockCnt == 0); #endif - OsPercpuGet()->schedFlag &= ~INT_PEND_RESCH; + rq->schedFlag &= ~INT_PEND_RESCH; LosTaskCB *runTask = OsCurrTaskGet(); - LosTaskCB *newTask = OsGetTopTask(); + LosTaskCB *newTask = GetTopTask(rq); if (runTask == newTask) { return; } - OsSchedTaskSwitch(runTask, newTask); + SchedTaskSwitch(runTask, newTask); } VOID LOS_Schedule(VOID) @@ -1148,7 +1217,7 @@ VOID LOS_Schedule(VOID) LosTaskCB *runTask = OsCurrTaskGet(); if (OS_INT_ACTIVE) { - OsPercpuGet()->schedFlag |= INT_PEND_RESCH; + OsSchedRunQuePendingSet(); return; } @@ -1163,7 +1232,7 @@ VOID LOS_Schedule(VOID) */ SCHEDULER_LOCK(intSave); - OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); + TimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); /* add run task back to ready queue */ OsSchedTaskEnQueue(runTask); diff --git a/kernel/base/sched/sched_sq/los_sortlink.c b/kernel/base/sched/sched_sq/los_sortlink.c index b193b6df..61733ece 100644 --- a/kernel/base/sched/sched_sq/los_sortlink.c +++ b/kernel/base/sched/sched_sq/los_sortlink.c @@ -30,20 +30,16 @@ */ #include "los_sortlink_pri.h" -#include "los_memory.h" -#include "los_exc.h" -#include "los_percpu_pri.h" -#include "los_sched_pri.h" #include "los_mp.h" -UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) +VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader) { LOS_ListInit(&sortLinkHeader->sortLink); + LOS_SpinInit(&sortLinkHeader->spinLock); sortLinkHeader->nodeNum = 0; - return LOS_OK; } -STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) +STATIC INLINE VOID AddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; @@ -77,104 +73,42 @@ STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLin } while (1); } -STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID) +VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu) { - Percpu *idleCpu = OsPercpuGetByID(0); - *idleCpuID = 0; - -#ifdef LOSCFG_KERNEL_SMP - UINT16 cpuID = 1; - UINT32 nodeNum = idleCpu->taskSortLink.nodeNum + idleCpu->swtmrSortLink.nodeNum; - - do { - Percpu *cpu = OsPercpuGetByID(cpuID); - UINT32 temp = cpu->taskSortLink.nodeNum + cpu->swtmrSortLink.nodeNum; - if (nodeNum > temp) { - idleCpu = cpu; - *idleCpuID = cpuID; - } - - cpuID++; - } while (cpuID < LOSCFG_KERNEL_CORE_NUM); -#endif - - return idleCpu; -} - -VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type) -{ - Percpu *cpu = NULL; - SortLinkAttribute *sortLinkHeader = NULL; - SPIN_LOCK_S *spinLock = NULL; - UINT16 idleCpu; - - if (OS_SCHEDULER_ACTIVE) { - cpu = OsFindIdleCpu(&idleCpu); - } else { - idleCpu = ArchCurrCpuid(); - cpu = OsPercpuGet(); - } - - if (type == OS_SORT_LINK_TASK) { - sortLinkHeader = &cpu->taskSortLink; - spinLock = &cpu->taskSortLinkSpin; - } else if (type == OS_SORT_LINK_SWTMR) { - sortLinkHeader = &cpu->swtmrSortLink; - spinLock = &cpu->swtmrSortLinkSpin; - } else { - LOS_Panic("Sort link type error : %u\n", type); - } - - LOS_SpinLock(spinLock); - SET_SORTLIST_VALUE(node, startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK); - OsAddNode2SortLink(sortLinkHeader, node); + LOS_SpinLock(&head->spinLock); + SET_SORTLIST_VALUE(node, responseTime); + AddNode2SortLink(head, node); #ifdef LOSCFG_KERNEL_SMP node->cpuid = idleCpu; +#endif + LOS_SpinUnlock(&head->spinLock); + +#ifdef LOSCFG_KERNEL_SMP if (idleCpu != ArchCurrCpuid()) { LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu)); } #endif - LOS_SpinUnlock(spinLock); } -VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type) +VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node) { -#ifdef LOSCFG_KERNEL_SMP - Percpu *cpu = OsPercpuGetByID(node->cpuid); -#else - Percpu *cpu = OsPercpuGetByID(0); -#endif - - SPIN_LOCK_S *spinLock = NULL; - SortLinkAttribute *sortLinkHeader = NULL; - if (type == OS_SORT_LINK_TASK) { - sortLinkHeader = &cpu->taskSortLink; - spinLock = &cpu->taskSortLinkSpin; - } else if (type == OS_SORT_LINK_SWTMR) { - sortLinkHeader = &cpu->swtmrSortLink; - spinLock = &cpu->swtmrSortLinkSpin; - } else { - LOS_Panic("Sort link type error : %u\n", type); - } - - LOS_SpinLock(spinLock); + LOS_SpinLock(&head->spinLock); if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { - OsDeleteNodeSortLink(sortLinkHeader, node); + OsDeleteNodeSortLink(head, node); } - LOS_SpinUnlock(spinLock); + LOS_SpinUnlock(&head->spinLock); } -UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList) +UINT32 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList) { - UINT64 currTimes = OsGetCurrSchedTimeCycle(); - if (currTimes >= targetSortList->responseTime) { + if (currTime >= targetSortList->responseTime) { return 0; } - return (UINT32)(targetSortList->responseTime - currTimes) / OS_CYCLE_PER_TICK; + return (UINT32)(targetSortList->responseTime - currTime); } -UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader) +UINT32 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader) { LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; @@ -183,6 +117,6 @@ UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader) } SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); - return OsSortLinkGetTargetExpireTime(listSorted); + return OsSortLinkGetTargetExpireTime(currTime, listSorted); } diff --git a/kernel/common/los_config.c b/kernel/common/los_config.c index 203ebcb2..b575e618 100644 --- a/kernel/common/los_config.c +++ b/kernel/common/los_config.c @@ -48,6 +48,7 @@ #include "los_spinlock.h" #include "los_swtmr_pri.h" #include "los_task_pri.h" +#include "los_sched_pri.h" #include "los_tick.h" #include "los_vm_boot.h" #include "los_smp.h" @@ -72,6 +73,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 EarliestInit(VOID) /* Must be placed at the beginning of the boot process */ OsSetMainTask(); OsCurrTaskSet(OsGetMainTask()); + OsSchedRunQueInit(); g_sysClock = OS_SYS_CLOCK; g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND; diff --git a/kernel/extended/power/los_pm.c b/kernel/extended/power/los_pm.c index 18110e4d..807ccaa5 100644 --- a/kernel/extended/power/los_pm.c +++ b/kernel/extended/power/los_pm.c @@ -185,7 +185,6 @@ STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm) LOS_SysSleepEnum mode; UINT32 prepare = 0; BOOL tickTimerStop = FALSE; - UINT64 currTime; ret = OsPmSuspendCheck(pm, &sysSuspendEarly, &deviceSuspend, &mode); if (ret != LOS_OK) { @@ -208,9 +207,8 @@ STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm) tickTimerStop = OsPmTickTimerStop(pm); if (!tickTimerStop) { - currTime = OsGetCurrSchedTimeCycle(); OsSchedResetSchedResponseTime(0); - OsSchedUpdateExpireTime(currTime); + OsSchedUpdateExpireTime(); } OsPmCpuSuspend(pm); diff --git a/kernel/extended/trace/los_trace.c b/kernel/extended/trace/los_trace.c index cb00f8dd..959b2578 100644 --- a/kernel/extended/trace/los_trace.c +++ b/kernel/extended/trace/los_trace.c @@ -37,6 +37,7 @@ #include "trace_cnv.h" #include "los_init.h" #include "los_process.h" +#include "los_sched_pri.h" #ifdef LOSCFG_KERNEL_SMP #include "los_mp.h" @@ -102,7 +103,7 @@ STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR id #ifdef LOSCFG_TRACE_FRAME_CORE_MSG frame->core.cpuId = ArchCurrCpuid(); frame->core.hwiActive = OS_INT_ACTIVE ? TRUE : FALSE; - frame->core.taskLockCnt = MIN(OsPercpuGet()->taskLockCnt, 0xF); /* taskLockCnt is 4 bits, max value = 0xF */ + frame->core.taskLockCnt = MIN(OsSchedLockCountGet(), 0xF); /* taskLockCnt is 4 bits, max value = 0xF */ frame->core.paramCount = paramCount; #endif diff --git a/net/telnet/src/telnet_dev.c b/net/telnet/src/telnet_dev.c index 0af77518..ab448be1 100644 --- a/net/telnet/src/telnet_dev.c +++ b/net/telnet/src/telnet_dev.c @@ -267,7 +267,7 @@ STATIC ssize_t TelnetWrite(struct file *file, const CHAR *buf, const size_t bufL if (telnetDev->clientFd != 0) { #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE /* DO NOT call blocking API in software timer task */ - if (((LosTaskCB*)OsCurrTaskGet())->taskEntry == (TSK_ENTRY_FUNC)OsSwtmrTask) { + if (OsIsSwtmrTask(OsCurrTaskGet())) { TelnetUnlock(); return ret; } diff --git a/shell/full/src/cmds/hwi_shellcmd.c b/shell/full/src/cmds/hwi_shellcmd.c index 5b755504..d36aefbf 100644 --- a/shell/full/src/cmds/hwi_shellcmd.c +++ b/shell/full/src/cmds/hwi_shellcmd.c @@ -35,6 +35,7 @@ #include "los_cpup_pri.h" #endif #include "los_hwi_pri.h" +#include "los_sys_pri.h" #include "shcmd.h"