From 6d8cef40c8ac2e83294a354399ad59c9ee8abcf5 Mon Sep 17 00:00:00 2001 From: zhushengle Date: Wed, 16 Mar 2022 20:28:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20swtmr=E6=9C=BA=E5=88=B6=E4=B8=8E?= =?UTF-8?q?=E8=B0=83=E5=BA=A6=E5=88=86=E7=A6=BB=EF=BC=8C=E8=B0=83=E5=BA=A6?= =?UTF-8?q?=E5=8F=AA=E9=92=88=E5=AF=B9=E9=80=9A=E7=94=A8=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E9=92=88=E5=AF=B9=E7=89=B9=E6=AE=8A=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: 原调度机制与软件定时器实现混合,调度时间链表存在两个链表, 任务切换时需要遍历两个链表才可以获取到最终的tick响应时间。 软件定时作为一个独立的功能,不应该和调度强耦合,而且软件定时 器作为一个任务,某个软件定时器的响应时间应该是软件定时器任务的 响应时间,不应该直接做为tick中断的响应时间。 方案描述: 1.将软件定时器从调度分离,作为一个独立的机制,从调度角度看其就是一个任务 2.软件定时器从调度分离之后,其timelist遍历从tick中断移动至软件定时器任务中 3.优化软件定时器的均衡调度 优势: 1.将软件定时器与调度完全分离,使得调度功能单一化,便于后续其它调度算法的引入 2.优化tick中断,减小tick中断耗时 3.优化通过写队列唤醒软件定时器任务去执行软件定时器钩子为插队列,减少软件定时 器机制本身的耗时,提升软件定时器的实时性 4.优化软件定时器均衡调度,使得软件定时器均匀分布于多核,提升软件定时器的实时性 Signed-off-by: zhushengle Change-Id: I07c01f134e69c1d9b7061ddf5a231df1ee99b68e --- arch/arm/arm/src/include/los_hwi_pri.h | 4 +- arch/arm/arm/src/los_exc.c | 58 +-- arch/arm/arm/src/los_hwi.c | 14 +- kernel/base/core/los_swtmr.c | 377 ++++++++++++++---- kernel/base/core/los_task.c | 2 +- kernel/base/include/los_sched_pri.h | 163 ++++---- kernel/base/include/los_sortlink_pri.h | 16 +- kernel/base/include/los_swtmr_pri.h | 35 +- kernel/base/misc/swtmr_shellcmd.c | 23 +- kernel/base/sched/sched_sq/los_sched.c | 176 ++------ kernel/base/sched/sched_sq/los_sortlink.c | 19 +- kernel/extended/cpup/los_cpup.c | 20 +- kernel/extended/trace/los_trace.c | 2 +- kernel/extended/trace/trace_offline.c | 4 +- kernel/include/los_trace.h | 2 +- testsuites/kernel/include/osTest.h | 2 +- .../core/task/smp/It_smp_los_task_081.c | 2 +- .../core/task/smp/It_smp_los_task_114.c | 2 +- .../core/task/smp/It_smp_los_task_115.c | 2 +- .../core/task/smp/It_smp_los_task_126.c | 2 +- .../core/task/smp/It_smp_los_task_127.c | 2 +- 21 files changed, 517 insertions(+), 410 deletions(-) diff --git a/arch/arm/arm/src/include/los_hwi_pri.h b/arch/arm/arm/src/include/los_hwi_pri.h index 27d0fdc9..e0b62adb 100644 --- a/arch/arm/arm/src/include/los_hwi_pri.h +++ b/arch/arm/arm/src/include/los_hwi_pri.h @@ -55,8 +55,8 @@ extern "C" { #define HWI_IS_REGISTED(num) ((&g_hwiForm[num])->pstNext != NULL) #endif extern VOID OsHwiInit(VOID); -extern VOID OsIncHwiFormCnt(UINT16 cpuId, UINT32 index); -extern UINT32 OsGetHwiFormCnt(UINT16 cpuId, UINT32 index); +extern VOID OsIncHwiFormCnt(UINT16 cpuid, UINT32 index); +extern UINT32 OsGetHwiFormCnt(UINT16 cpuid, UINT32 index); extern CHAR *OsGetHwiFormName(UINT32 index); extern VOID OsInterrupt(UINT32 intNum); extern VOID OsSyscallHandleInit(VOID); diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index 672e9396..3c8514c8 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -74,7 +74,7 @@ STATIC UINTPTR g_minAddr; STATIC UINTPTR g_maxAddr; -STATIC UINT32 g_currHandleExcCpuID = INVALID_CPUID; +STATIC UINT32 g_currHandleExcCpuid = INVALID_CPUID; VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr); UINT32 g_curNestCount[LOSCFG_KERNEL_CORE_NUM] = { 0 }; BOOL g_excFromUserMode[LOSCFG_KERNEL_CORE_NUM]; @@ -112,11 +112,11 @@ STATIC const StackInfo g_excStack[] = { UINT32 OsGetSystemStatus(VOID) { UINT32 flag; - UINT32 cpuID = g_currHandleExcCpuID; + UINT32 cpuid = g_currHandleExcCpuid; - if (cpuID == INVALID_CPUID) { + if (cpuid == INVALID_CPUID) { flag = OS_SYSTEM_NORMAL; - } else if (cpuID == ArchCurrCpuid()) { + } else if (cpuid == ArchCurrCpuid()) { flag = OS_SYSTEM_EXC_CURR_CPU; } else { flag = OS_SYSTEM_EXC_OTHER_CPU; @@ -531,11 +531,11 @@ VOID OsDumpContextMem(const ExcContext *excBufAddr) STATIC VOID OsExcRestore(VOID) { - UINT32 currCpuID = ArchCurrCpuid(); + UINT32 currCpuid = ArchCurrCpuid(); - g_excFromUserMode[currCpuID] = FALSE; - g_intCount[currCpuID] = 0; - g_curNestCount[currCpuID] = 0; + g_excFromUserMode[currCpuid] = FALSE; + g_intCount[currCpuid] = 0; + g_curNestCount[currCpuid] = 0; #ifdef LOSCFG_KERNEL_SMP OsCpuStatusSet(CPU_RUNNING); #endif @@ -556,15 +556,15 @@ STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) #ifdef LOSCFG_KERNEL_SMP LOS_SpinLock(&g_excSerializerSpin); if (g_nextExcWaitCpu != INVALID_CPUID) { - g_currHandleExcCpuID = g_nextExcWaitCpu; + g_currHandleExcCpuid = g_nextExcWaitCpu; g_nextExcWaitCpu = INVALID_CPUID; } else { - g_currHandleExcCpuID = INVALID_CPUID; + g_currHandleExcCpuid = INVALID_CPUID; } g_currHandleExcPID = OS_INVALID_VALUE; LOS_SpinUnlock(&g_excSerializerSpin); #else - g_currHandleExcCpuID = INVALID_CPUID; + g_currHandleExcCpuid = INVALID_CPUID; #endif #ifdef LOSCFG_KERNEL_SMP @@ -979,14 +979,14 @@ VOID OsDataAbortExcHandleEntry(ExcContext *excBufAddr) #define EXC_WAIT_INTER 50U #define EXC_WAIT_TIME 2000U -STATIC VOID WaitAllCpuStop(UINT32 cpuID) +STATIC VOID WaitAllCpuStop(UINT32 cpuid) { UINT32 i; UINT32 time = 0; while (time < EXC_WAIT_TIME) { for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { - if ((i != cpuID) && !OsCpuStatusIsHalt(i)) { + if ((i != cpuid) && !OsCpuStatusIsHalt(i)) { LOS_Mdelay(EXC_WAIT_INTER); time += EXC_WAIT_INTER; break; @@ -1000,19 +1000,19 @@ STATIC VOID WaitAllCpuStop(UINT32 cpuID) return; } -STATIC VOID OsWaitOtherCoresHandleExcEnd(UINT32 currCpuID) +STATIC VOID OsWaitOtherCoresHandleExcEnd(UINT32 currCpuid) { while (1) { LOS_SpinLock(&g_excSerializerSpin); - if ((g_currHandleExcCpuID == INVALID_CPUID) || (g_currHandleExcCpuID == currCpuID)) { - g_currHandleExcCpuID = currCpuID; + if ((g_currHandleExcCpuid == INVALID_CPUID) || (g_currHandleExcCpuid == currCpuid)) { + g_currHandleExcCpuid = currCpuid; g_currHandleExcPID = OsCurrProcessGet()->processID; LOS_SpinUnlock(&g_excSerializerSpin); break; } if (g_nextExcWaitCpu == INVALID_CPUID) { - g_nextExcWaitCpu = currCpuID; + g_nextExcWaitCpu = currCpuid; } LOS_SpinUnlock(&g_excSerializerSpin); LOS_Mdelay(EXC_WAIT_INTER); @@ -1021,7 +1021,7 @@ STATIC VOID OsWaitOtherCoresHandleExcEnd(UINT32 currCpuID) STATIC VOID OsCheckAllCpuStatus(VOID) { - UINT32 currCpuID = ArchCurrCpuid(); + UINT32 currCpuid = ArchCurrCpuid(); UINT32 ret, target; OsCpuStatusSet(CPU_EXC); @@ -1029,17 +1029,17 @@ STATIC VOID OsCheckAllCpuStatus(VOID) LOS_SpinLock(&g_excSerializerSpin); /* Only the current CPU anomaly */ - if (g_currHandleExcCpuID == INVALID_CPUID) { - g_currHandleExcCpuID = currCpuID; + if (g_currHandleExcCpuid == INVALID_CPUID) { + g_currHandleExcCpuid = currCpuid; g_currHandleExcPID = OsCurrProcessGet()->processID; LOS_SpinUnlock(&g_excSerializerSpin); #ifndef LOSCFG_SAVE_EXCINFO - if (g_excFromUserMode[currCpuID] == FALSE) { - target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(currCpuID)); + if (g_excFromUserMode[currCpuid] == FALSE) { + target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(currCpuid)); HalIrqSendIpi(target, LOS_MP_IPI_HALT); } #endif - } else if (g_excFromUserMode[currCpuID] == TRUE) { + } else if (g_excFromUserMode[currCpuid] == TRUE) { /* Both cores raise exceptions, and the current core is a user-mode exception. * Both cores are abnormal and come from the same process */ @@ -1051,12 +1051,12 @@ STATIC VOID OsCheckAllCpuStatus(VOID) } LOS_SpinUnlock(&g_excSerializerSpin); - OsWaitOtherCoresHandleExcEnd(currCpuID); + OsWaitOtherCoresHandleExcEnd(currCpuid); } else { - if ((g_currHandleExcCpuID < LOSCFG_KERNEL_CORE_NUM) && (g_excFromUserMode[g_currHandleExcCpuID] == TRUE)) { - g_currHandleExcCpuID = currCpuID; + if ((g_currHandleExcCpuid < LOSCFG_KERNEL_CORE_NUM) && (g_excFromUserMode[g_currHandleExcCpuid] == TRUE)) { + g_currHandleExcCpuid = currCpuid; LOS_SpinUnlock(&g_excSerializerSpin); - target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(currCpuID)); + target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(currCpuid)); HalIrqSendIpi(target, LOS_MP_IPI_HALT); } else { LOS_SpinUnlock(&g_excSerializerSpin); @@ -1066,7 +1066,7 @@ STATIC VOID OsCheckAllCpuStatus(VOID) #ifndef LOSCFG_SAVE_EXCINFO /* use halt ipi to stop other active cores */ if (g_excFromUserMode[ArchCurrCpuid()] == FALSE) { - WaitAllCpuStop(currCpuID); + WaitAllCpuStop(currCpuid); } #endif } @@ -1077,7 +1077,7 @@ STATIC VOID OsCheckCpuStatus(VOID) #ifdef LOSCFG_KERNEL_SMP OsCheckAllCpuStatus(); #else - g_currHandleExcCpuID = ArchCurrCpuid(); + g_currHandleExcCpuid = ArchCurrCpuid(); #endif } diff --git a/arch/arm/arm/src/los_hwi.c b/arch/arm/arm/src/los_hwi.c index 4d1c250f..24271524 100644 --- a/arch/arm/arm/src/los_hwi.c +++ b/arch/arm/arm/src/los_hwi.c @@ -48,9 +48,9 @@ HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM]; STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0}; STATIC UINT32 g_hwiFormCnt[LOSCFG_KERNEL_CORE_NUM][OS_HWI_MAX_NUM] = {0}; -UINT32 OsGetHwiFormCnt(UINT16 cpuId, UINT32 index) +UINT32 OsGetHwiFormCnt(UINT16 cpuid, UINT32 index) { - return g_hwiFormCnt[cpuId][index]; + return g_hwiFormCnt[cpuid][index]; } CHAR *OsGetHwiFormName(UINT32 index) @@ -69,14 +69,14 @@ VOID OsInterrupt(UINT32 intNum) { HwiHandleForm *hwiForm = NULL; UINT32 *intCnt = NULL; - UINT16 cpuId = ArchCurrCpuid(); + UINT16 cpuid = ArchCurrCpuid(); /* Must keep the operation at the beginning of the interface */ - intCnt = &g_intCount[cpuId]; + intCnt = &g_intCount[cpuid]; *intCnt = *intCnt + 1; #ifdef LOSCFG_CPUP_INCLUDE_IRQ - OsCpupIrqStart(cpuId); + OsCpupIrqStart(cpuid); #endif OsSchedIrqStartTime(); @@ -101,13 +101,13 @@ VOID OsInterrupt(UINT32 intNum) #ifndef LOSCFG_NO_SHARED_IRQ } #endif - ++g_hwiFormCnt[cpuId][intNum]; + ++g_hwiFormCnt[cpuid][intNum]; OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, intNum); OsSchedIrqUpdateUsedTime(); #ifdef LOSCFG_CPUP_INCLUDE_IRQ - OsCpupIrqEnd(cpuId, intNum); + OsCpupIrqEnd(cpuid, intNum); #endif /* Must keep the operation at the end of the interface */ *intCnt = *intCnt - 1; diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index cb7245ce..a5cec168 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -43,6 +43,9 @@ #error "swtmr maxnum cannot be zero" #endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */ +STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr); +STATIC INLINE UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid); + LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space */ LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Handler */ LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */ @@ -52,6 +55,14 @@ 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)) +typedef struct { + SortLinkAttribute swtmrSortLink; + LosTaskCB *swtmrTask; /* software timer task id */ + LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */ +} SwtmrRunQue; + +STATIC SwtmrRunQue g_swtmrRunQue[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) STATIC SwtmrDebugData *g_swtmrDebugData = NULL; @@ -100,40 +111,34 @@ STATIC VOID SwtmrDebugDataInit(VOID) #endif } -STATIC INLINE VOID SwtmrDebugDataUpdate(SWTMR_CTRL_S *swtmr, UINT32 ticks) +STATIC INLINE VOID SwtmrDebugDataUpdate(SWTMR_CTRL_S *swtmr, UINT32 ticks, UINT32 times) { #ifdef LOSCFG_SWTMR_DEBUG SwtmrDebugData *data = &g_swtmrDebugData[swtmr->usTimerID]; - data->startTime = swtmr->startTime; if (data->period != ticks) { - data->waitCount = 0; - data->runCount = 0; - data->waitTime = 0; - data->waitTimeMax = 0; - data->runTime = 0; - data->runTimeMax = 0; - data->readyTime = 0; - data->readyTimeMax = 0; + (VOID)memset_s(&data->base, sizeof(SwtmrDebugBase), 0, sizeof(SwtmrDebugBase)); data->period = ticks; } + data->base.startTime = swtmr->startTime; + data->base.times += times; #endif } -STATIC INLINE VOID SwtmrDebugDataStart(SWTMR_CTRL_S *swtmr, UINT16 cpuId) +STATIC INLINE VOID SwtmrDebugDataStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid) { #ifdef LOSCFG_SWTMR_DEBUG SwtmrDebugData *data = &g_swtmrDebugData[swtmr->usTimerID]; data->swtmrUsed = TRUE; data->handler = swtmr->pfnHandler; - data->cpuId = cpuId; + data->cpuid = cpuid; #endif } -STATIC INLINE VOID SwtmrDebugWaitTimeCalculate(UINT32 timerId, SwtmrHandlerItemPtr swtmrHandler) +STATIC INLINE VOID SwtmrDebugWaitTimeCalculate(UINT32 swtmrID, SwtmrHandlerItemPtr swtmrHandler) { #ifdef LOSCFG_SWTMR_DEBUG - SwtmrDebugData *data = &g_swtmrDebugData[timerId]; - swtmrHandler->swtmrId = timerId; + SwtmrDebugBase *data = &g_swtmrDebugData[swtmrID].base; + swtmrHandler->swtmrID = swtmrID; UINT64 currTime = OsGetCurrSchedTimeCycle(); UINT64 waitTime = currTime - data->startTime; data->waitTime += waitTime; @@ -141,15 +146,14 @@ STATIC INLINE VOID SwtmrDebugWaitTimeCalculate(UINT32 timerId, SwtmrHandlerItemP data->waitTimeMax = waitTime; } data->readyStartTime = currTime; - LOS_ASSERT(waitTime >= OS_SWTMR_PERIOD_TO_CYCLE(data->period)); data->waitCount++; #endif } -STATIC INLINE VOID SwtmrDebugDataClear(UINT32 timerId) +STATIC INLINE VOID SwtmrDebugDataClear(UINT32 swtmrID) { #ifdef LOSCFG_SWTMR_DEBUG - (VOID)memset_s(&g_swtmrDebugData[timerId], sizeof(SwtmrDebugData), 0, sizeof(SwtmrDebugData)); + (VOID)memset_s(&g_swtmrDebugData[swtmrID], sizeof(SwtmrDebugData), 0, sizeof(SwtmrDebugData)); #endif } @@ -157,7 +161,7 @@ STATIC INLINE VOID SwtmrHandler(SwtmrHandlerItemPtr swtmrHandle) { #ifdef LOSCFG_SWTMR_DEBUG UINT32 intSave; - SwtmrDebugData *data = &g_swtmrDebugData[swtmrHandle->swtmrId]; + SwtmrDebugBase *data = &g_swtmrDebugData[swtmrHandle->swtmrID].base; UINT64 startTime = OsGetCurrSchedTimeCycle(); #endif swtmrHandle->handler(swtmrHandle->arg); @@ -178,16 +182,102 @@ STATIC INLINE VOID SwtmrHandler(SwtmrHandlerItemPtr swtmrHandle) #endif } +STATIC INLINE VOID SwtmrWake(SwtmrRunQue *srq, UINT64 startTime, SortLinkList *sortList) +{ + UINT32 intSave; + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); + LOS_ASSERT(swtmrHandler != NULL); + + OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr); + + SWTMR_LOCK(intSave); + swtmrHandler->handler = swtmr->pfnHandler; + swtmrHandler->arg = swtmr->uwArg; + LOS_ListTailInsert(&srq->swtmrHandlerQueue, &swtmrHandler->node); + SwtmrDebugWaitTimeCalculate(swtmr->usTimerID, swtmrHandler); + + if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) { + SwtmrDelete(swtmr); + + if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) { + swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; + } else { + swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; + } + } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) { + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + } else { + swtmr->uwOverrun++; + swtmr->startTime = startTime; + (VOID)SwtmrToStart(swtmr, ArchCurrCpuid()); + } + + SWTMR_UNLOCK(intSave); +} + +STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunQue *srq) +{ + UINT32 intSave; + SortLinkAttribute *swtmrSortLink = &srq->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_SpinLockSave(&swtmrSortLink->spinLock, &intSave); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); + 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); + UINT64 startTime = GET_SORTLIST_VALUE(sortList); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); + + SwtmrWake(srq, startTime, sortList); + + LOS_SpinLockSave(&swtmrSortLink->spinLock, &intSave); + if (LOS_ListEmpty(listObject)) { + break; + } + + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + } + + LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); + return; +} + STATIC VOID SwtmrTask(VOID) { - SwtmrHandlerItemPtr swtmrHandlePtr = NULL; SwtmrHandlerItem swtmrHandle; - UINT32 ret, swtmrHandlerQueue; + UINT32 intSave; + UINT64 waitTime; - swtmrHandlerQueue = OsSchedSwtmrHandlerQueueGet(); + SwtmrRunQue *srq = &g_swtmrRunQue[ArchCurrCpuid()]; + LOS_DL_LIST *head = &srq->swtmrHandlerQueue; for (;;) { - ret = LOS_QueueRead(swtmrHandlerQueue, &swtmrHandlePtr, sizeof(CHAR *), LOS_WAIT_FOREVER); - if ((ret == LOS_OK) && (swtmrHandlePtr != NULL)) { + waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink); + if (waitTime != 0) { + SCHEDULER_LOCK(intSave); + OsSchedDelay(srq->swtmrTask, waitTime); + OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, srq->swtmrTask); + SCHEDULER_UNLOCK(intSave); + } + + ScanSwtmrTimeList(srq); + + while (!LOS_ListEmpty(head)) { + SwtmrHandlerItemPtr swtmrHandlePtr = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(head), SwtmrHandlerItem, node); + LOS_ListDelete(&swtmrHandlePtr->node); + (VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem)); (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr); SwtmrHandler(&swtmrHandle); @@ -217,6 +307,11 @@ STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID) return ret; } +UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid) +{ + return g_swtmrRunQue[cpuid].swtmrTask->taskID; +} + BOOL OsIsSwtmrTask(const LosTaskCB *taskCB) { if (taskCB->taskEntry == (TSK_ENTRY_FUNC)SwtmrTask) { @@ -242,7 +337,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) SWTMR_CTRL_S *swtmr = NULL; UINT32 swtmrHandlePoolSize; UINT32 cpuid = ArchCurrCpuid(); - UINT32 swtmrTaskID, swtmrHandlerQueue; + UINT32 swtmrTaskID; if (cpuid == 0) { size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT; @@ -270,17 +365,20 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem)); if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, g_swtmrHandlerPool); ret = LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM; goto ERROR; } - SwtmrDebugDataInit(); - } + for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + SwtmrRunQue *srq = &g_swtmrRunQue[index]; + /* The linked list of all cores must be initialized at core 0 startup for load balancing */ + OsSortLinkInit(&srq->swtmrSortLink); + LOS_ListInit(&srq->swtmrHandlerQueue); + srq->swtmrTask = NULL; + } - 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; + SwtmrDebugDataInit(); } ret = SwtmrTaskCreate(cpuid, &swtmrTaskID); @@ -289,7 +387,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) goto ERROR; } - OsSchedRunQueSwtmrInit(swtmrTaskID, swtmrHandlerQueue); + SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + srq->swtmrTask = OsGetTaskCB(swtmrTaskID); return LOS_OK; ERROR: @@ -297,13 +396,75 @@ ERROR: return ret; } -/* - * Description: Start Software Timer - * Input : swtmr --- Need to start software timer - */ -LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) +#ifdef LOSCFG_KERNEL_SMP +STATIC INLINE VOID FindIdleSwtmrRunQue(UINT16 *idleCpuid) +{ + SwtmrRunQue *idleRq = &g_swtmrRunQue[0]; + UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->swtmrSortLink); + UINT16 cpuid = 1; + do { + SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + UINT32 temp = OsGetSortLinkNodeNum(&srq->swtmrSortLink); + if (nodeNum > temp) { + *idleCpuid = cpuid; + nodeNum = temp; + } + cpuid++; + } while (cpuid < LOSCFG_KERNEL_CORE_NUM); +} +#endif + +STATIC INLINE VOID AddSwtmr2TimeList(SortLinkList *node, UINT64 responseTime, UINT16 cpuid) +{ + SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + OsAdd2SortLink(&srq->swtmrSortLink, node, responseTime, cpuid); +} + +STATIC INLINE VOID DeSwtmrFromTimeList(SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + UINT16 cpuid = OsGetSortLinkNodeCpuid(node); +#else + UINT16 cpuid = 0; +#endif + SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + OsDeleteFromSortLink(&srq->swtmrSortLink, node); + return; +} + +STATIC VOID SwtmrAdjustCheck(UINT16 cpuid, UINT64 responseTime) +{ + UINT32 ret; + UINT32 intSave; + SwtmrRunQue *srq = &g_swtmrRunQue[cpuid]; + SCHEDULER_LOCK(intSave); + if ((srq->swtmrTask == NULL) || !OsTaskIsBlocked(srq->swtmrTask)) { + SCHEDULER_UNLOCK(intSave); + return; + } + + if (responseTime >= GET_SORTLIST_VALUE(&srq->swtmrTask->sortList)) { + SCHEDULER_UNLOCK(intSave); + return; + } + + ret = OsSchedAdjustTaskFromTimeList(srq->swtmrTask, responseTime); + SCHEDULER_UNLOCK(intSave); + if (ret != LOS_OK) { + return; + } + + if (cpuid == ArchCurrCpuid()) { + OsSchedUpdateExpireTime(); + } else { + LOS_MpSchedule(CPUID_TO_AFFI_MASK(cpuid)); + } +} + +STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid) { UINT32 ticks; + UINT32 times = 0; if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || @@ -314,17 +475,45 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) } swtmr->ucState = OS_SWTMR_STATUS_TICKING; - OsSchedAddSwtmr2TimeList(&swtmr->stSortList, swtmr->startTime, ticks); - SwtmrDebugDataUpdate(swtmr, ticks); - OsSchedUpdateExpireTime(); - return; + UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK; + UINT64 responseTime = swtmr->startTime + period; + UINT64 currTime = OsGetCurrSchedTimeCycle(); + if (responseTime < currTime) { + times = (UINT32)((currTime - swtmr->startTime) / period); + swtmr->startTime += times * period; + responseTime = swtmr->startTime + period; + PRINT_WARN("Swtmr already timeout! SwtmrID: %u\n", swtmr->usTimerID); + } + + AddSwtmr2TimeList(&swtmr->stSortList, responseTime, cpuid); + SwtmrDebugDataUpdate(swtmr, ticks, times); + return responseTime; +} + +/* + * Description: Start Software Timer + * Input : swtmr --- Need to start software timer + */ +STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr) +{ + UINT64 responseTime; + UINT16 idleCpu = 0; +#ifdef LOSCFG_KERNEL_SMP + FindIdleSwtmrRunQue(&idleCpu); +#endif + swtmr->startTime = OsGetCurrSchedTimeCycle(); + responseTime = SwtmrToStart(swtmr, idleCpu); + + SwtmrDebugDataStart(swtmr, idleCpu); + + SwtmrAdjustCheck(idleCpu, responseTime); } /* * Description: Delete Software Timer * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL. */ -STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) +STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr) { /* insert to free list */ LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); @@ -334,51 +523,66 @@ STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) SwtmrDebugDataClear(swtmr->usTimerID); } -VOID OsSwtmrWake(SchedRunQue *rq, UINT64 startTime, SortLinkList *sortList) +STATIC INLINE VOID SwtmrRestart(UINT64 startTime, SortLinkList *sortList, UINT16 cpuid) { + UINT32 intSave; + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + SWTMR_LOCK(intSave); + swtmr->startTime = startTime; + (VOID)SwtmrToStart(swtmr, cpuid); + SWTMR_UNLOCK(intSave); +} - 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; - SwtmrDebugWaitTimeCalculate(swtmr->usTimerID, swtmrHandler); +VOID OsSwtmrResponseTimeReset(UINT64 startTime) +{ + UINT16 cpuid = ArchCurrCpuid(); + SortLinkAttribute *swtmrSortLink = &g_swtmrRunQue[cpuid].swtmrSortLink; + LOS_DL_LIST *listHead = &swtmrSortLink->sortLink; + LOS_DL_LIST *listNext = listHead->pstNext; - if (LOS_QueueWrite(rq->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) { - (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandler); - } - } + LOS_SpinLock(&swtmrSortLink->spinLock); + while (listNext != listHead) { + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listNext, SortLinkList, sortLinkNode); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlock(&swtmrSortLink->spinLock); - if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) { - OsSwtmrDelete(swtmr); + SwtmrRestart(startTime, sortList, cpuid); - if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) { - swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; - } else { - swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; + LOS_SpinLock(&swtmrSortLink->spinLock); + listNext = listNext->pstNext; + } + LOS_SpinUnlock(&swtmrSortLink->spinLock); +} + +STATIC INLINE BOOL SwtmrRunQueFind(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; } - } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) { - swtmr->ucState = OS_SWTMR_STATUS_CREATED; - } else { - swtmr->uwOverrun++; - swtmr->startTime = startTime; - OsSwtmrStart(swtmr); + list = list->pstNext; } - LOS_SpinUnlock(&g_swtmrSpin); + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return FALSE; } -VOID OsSwtmrRestart(UINT64 startTime, SortLinkList *sortList) +STATIC BOOL SwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) { - UINT32 intSave; - - SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); - SWTMR_LOCK(intSave); - swtmr->startTime = startTime; - OsSwtmrStart(swtmr); - SWTMR_UNLOCK(intSave); + for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + SortLinkAttribute *swtmrSortLink = &g_swtmrRunQue[ArchCurrCpuid()].swtmrSortLink; + if (SwtmrRunQueFind(swtmrSortLink, checkFunc, arg)) { + return TRUE; + } + } + return FALSE; } BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) @@ -386,7 +590,7 @@ BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) UINT32 intSave; SWTMR_LOCK(intSave); - BOOL find = OsSchedSwtmrTimeListFind(checkFunc, arg); + BOOL find = SwtmrTimeListFind(checkFunc, arg); SWTMR_UNLOCK(intSave); return find; } @@ -398,7 +602,8 @@ BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) { UINT64 currTime = OsGetCurrSchedTimeCycle(); - UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &OsSchedRunQue()->swtmrSortLink) / OS_CYCLE_PER_TICK); + SwtmrRunQue *srq = &g_swtmrRunQue[ArchCurrCpuid()]; + UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &srq->swtmrSortLink) / OS_CYCLE_PER_TICK); if (time > OS_INVALID_VALUE) { time = OS_INVALID_VALUE; } @@ -409,14 +614,12 @@ LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) * Description: Stop of Software Timer interface * Input : swtmr --- the software timer control handler */ -LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) +STATIC VOID SwtmrStop(SWTMR_CTRL_S *swtmr) { - OsSchedDeSwtmrFromTimeList(&swtmr->stSortList); - swtmr->ucState = OS_SWTMR_STATUS_CREATED; swtmr->uwOverrun = 0; - OsSchedUpdateExpireTime(); + DeSwtmrFromTimeList(&swtmr->stSortList); } /* @@ -514,12 +717,10 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) * then start the swtmr again. */ case OS_SWTMR_STATUS_TICKING: - OsSwtmrStop(swtmr); + SwtmrStop(swtmr); /* fall-through */ case OS_SWTMR_STATUS_CREATED: - swtmr->startTime = OsGetCurrSchedTimeCycle(); - SwtmrDebugDataStart(swtmr, ArchCurrCpuid()); - OsSwtmrStart(swtmr); + SwtmrStart(swtmr); break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; @@ -559,7 +760,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) ret = LOS_ERRNO_SWTMR_NOT_STARTED; break; case OS_SWTMR_STATUS_TICKING: - OsSwtmrStop(swtmr); + SwtmrStop(swtmr); break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; @@ -637,10 +838,10 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; case OS_SWTMR_STATUS_TICKING: - OsSwtmrStop(swtmr); + SwtmrStop(swtmr); /* fall-through */ case OS_SWTMR_STATUS_CREATED: - OsSwtmrDelete(swtmr); + SwtmrDelete(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 d2984ee2..eee247f9 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -925,7 +925,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) } SCHEDULER_LOCK(intSave); - OsSchedDelay(runTask, tick); + OsSchedDelay(runTask, OS_SCHED_TICK_TO_CYCLE(tick)); OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, runTask); SCHEDULER_UNLOCK(intSave); diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index 08552b5b..cd2d478d 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -48,6 +48,7 @@ #ifdef LOSCFG_KERNEL_LITEIPC #include "hm_liteipc.h" #endif +#include "los_mp.h" #ifdef __cplusplus #if __cplusplus @@ -55,9 +56,11 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) -#define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100) -#define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(((UINT64)-1) - 1U) +#define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) +#define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100) +#define OS_SCHED_MAX_RESPONSE_TIME OS_SORT_LINK_INVALID_TIME +#define OS_SCHED_TICK_TO_CYCLE(ticks) ((UINT64)ticks * OS_CYCLE_PER_TICK) +#define AFFI_MASK_TO_CPUID(mask) ((UINT16)((mask) - 1)) extern UINT32 g_taskScheduled; #define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) @@ -78,18 +81,17 @@ typedef enum { 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]; +VOID OsSchedUpdateExpireTime(VOID); + STATIC INLINE SchedRunQue *OsSchedRunQue(VOID) { return &g_schedRunQue[ArchCurrCpuid()]; @@ -190,75 +192,8 @@ 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); /** * @ingroup los_sched @@ -359,11 +294,11 @@ typedef struct { 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 */ - UINT32 waitTimes; /**< Task delay time, tick number */ SortLinkList sortList; /**< Task sortlink node */ UINT32 stackSize; /**< Task stack size */ @@ -480,6 +415,78 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID) runTask->irqStartTime = OsGetCurrSchedTimeCycle(); } +#ifdef LOSCFG_KERNEL_SMP +STATIC INLINE VOID FindIdleRunQue(UINT16 *idleCpuid) +{ + SchedRunQue *idleRq = OsSchedRunQueByID(0); + UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->taskSortLink); + UINT16 cpuid = 1; + do { + SchedRunQue *rq = OsSchedRunQueByID(cpuid); + UINT32 temp = OsGetSortLinkNodeNum(&rq->taskSortLink); + if (nodeNum > temp) { + *idleCpuid = cpuid; + nodeNum = temp; + } + cpuid++; + } while (cpuid < LOSCFG_KERNEL_CORE_NUM); +} +#endif + +STATIC INLINE VOID OsSchedAddTask2TimeList(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); + } +#else + UINT16 cpuid = 0; +#endif + + SchedRunQue *rq = OsSchedRunQueByID(cpuid); + OsAdd2SortLink(&rq->taskSortLink, &taskCB->sortList, responseTime, cpuid); +#ifdef LOSCFG_KERNEL_SMP + if ((cpuid != ArchCurrCpuid()) && (responseTime < rq->responseTime)) { + rq->schedFlag |= INT_PEND_TICK; + LOS_MpSchedule(CPUID_TO_AFFI_MASK(cpuid)); + } +#endif +} + +STATIC INLINE VOID OsSchedDeTaskFromTimeList(LosTaskCB *taskCB) +{ + SortLinkList *node = &taskCB->sortList; +#ifdef LOSCFG_KERNEL_SMP + SchedRunQue *rq = OsSchedRunQueByID(node->cpuid); +#else + SchedRunQue *rq = OsSchedRunQueByID(0); +#endif + UINT64 oldResponseTime = GET_SORTLIST_VALUE(node); + OsDeleteFromSortLink(&rq->taskSortLink, node); + if (oldResponseTime <= rq->responseTime) { + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + } +} + +STATIC INLINE UINT32 OsSchedAdjustTaskFromTimeList(LosTaskCB *taskCB, UINT64 responseTime) +{ + UINT32 ret; + SortLinkList *node = &taskCB->sortList; +#ifdef LOSCFG_KERNEL_SMP + UINT16 cpuid = node->cpuid; +#else + UINT16 cpuid = 0; +#endif + SchedRunQue *rq = OsSchedRunQueByID(cpuid); + ret = OsSortLinkAdjustNodeResponseTime(&rq->taskSortLink, node, responseTime); + if (ret == LOS_OK) { + rq->schedFlag |= INT_PEND_TICK; + } + return ret; +} + /* * Schedule flag, one bit represents one core. * This flag is used to prevent kernel scheduling before OSStartToRun. @@ -494,7 +501,6 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID) VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask); VOID OsSchedResetSchedResponseTime(UINT64 responseTime); -VOID OsSchedUpdateExpireTime(VOID); VOID OsSchedToUserReleaseLock(VOID); VOID OsSchedTaskDeQueue(LosTaskCB *taskCB); VOID OsSchedTaskEnQueue(LosTaskCB *taskCB); @@ -504,7 +510,7 @@ BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priori BOOL OsSchedModifyProcessSchedParam(UINT32 pid, UINT16 policy, UINT16 priority); VOID OsSchedSuspend(LosTaskCB *taskCB); BOOL OsSchedResume(LosTaskCB *taskCB); -VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick); +VOID OsSchedDelay(LosTaskCB *runTask, UINT64 waitTime); VOID OsSchedYield(VOID); VOID OsSchedTaskExit(LosTaskCB *taskCB); VOID OsSchedTick(VOID); @@ -525,14 +531,13 @@ VOID OsSchedIrqEndCheckNeedSched(VOID); */ LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList); +#ifdef LOSCFG_SCHED_DEBUG #ifdef LOSCFG_SCHED_TICK_DEBUG VOID OsSchedDebugRecordData(VOID); #endif - UINT32 OsShellShowTickRespo(VOID); - UINT32 OsShellShowSchedParam(VOID); - +#endif #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h index 89fa1761..788947d3 100644 --- a/kernel/base/include/los_sortlink_pri.h +++ b/kernel/base/include/los_sortlink_pri.h @@ -72,28 +72,42 @@ STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, LOS_DL_LIST *head = &sortHeader->sortLink; LOS_DL_LIST *list = head->pstNext; + LOS_SpinLock(&sortHeader->spinLock); if (LOS_ListEmpty(head)) { + LOS_SpinUnlock(&sortHeader->spinLock); return OS_SORT_LINK_INVALID_TIME - tickPrecision; } SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); if (listSorted->responseTime <= (startTime + tickPrecision)) { + LOS_SpinUnlock(&sortHeader->spinLock); return startTime + tickPrecision; } + LOS_SpinUnlock(&sortHeader->spinLock); return listSorted->responseTime; } -STATIC INLINE UINT32 OsGetSortLinkNodeNum(SortLinkAttribute *head) +STATIC INLINE UINT32 OsGetSortLinkNodeNum(const SortLinkAttribute *head) { return head->nodeNum; } +STATIC INLINE UINT16 OsGetSortLinkNodeCpuid(const SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + return node->cpuid; +#else + return 0; +#endif +} + VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader); VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu); VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node); UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList); UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader); +UINT32 OsSortLinkAdjustNodeResponseTime(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_swtmr_pri.h b/kernel/base/include/los_swtmr_pri.h index 8859c396..38f97a0e 100644 --- a/kernel/base/include/los_swtmr_pri.h +++ b/kernel/base/include/los_swtmr_pri.h @@ -66,8 +66,9 @@ typedef struct { SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */ UINTPTR arg; /**< Parameter passed in when the callback function that handles software timer timeout is called */ + LOS_DL_LIST node; #ifdef LOSCFG_SWTMR_DEBUG - UINT32 swtmrId; + UINT32 swtmrID; #endif } SwtmrHandlerItem; @@ -103,29 +104,35 @@ extern SWTMR_CTRL_S *g_swtmrCBArray; * @see LOS_SwtmrStop */ +extern UINT32 OsSwtmrGetNextTimeout(VOID); extern BOOL OsIsSwtmrTask(const LosTaskCB *taskCB); -extern VOID OsSwtmrRestart(UINT64 startTime, SortLinkList *sortList); -extern VOID OsSwtmrWake(SchedRunQue *rq, UINT64 currTime, SortLinkList *sortList); +extern VOID OsSwtmrResponseTimeReset(UINT64 startTime); extern UINT32 OsSwtmrInit(VOID); extern VOID OsSwtmrRecycle(UINT32 processID); extern BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg); extern SPIN_LOCK_S g_swtmrSpin; +extern UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid); #ifdef LOSCFG_SWTMR_DEBUG typedef struct { - UINT64 startTime; - UINT64 waitTimeMax; - UINT64 waitTime; - UINT64 waitCount; - UINT64 readyStartTime; - UINT64 readyTime; - UINT64 readyTimeMax; - UINT64 runTime; - UINT64 runTimeMax; - UINT64 runCount; + UINT64 startTime; + UINT64 waitTimeMax; + UINT64 waitTime; + UINT64 waitCount; + UINT64 readyStartTime; + UINT64 readyTime; + UINT64 readyTimeMax; + UINT64 runTime; + UINT64 runTimeMax; + UINT64 runCount; + UINT32 times; +} SwtmrDebugBase; + +typedef struct { + SwtmrDebugBase base; SWTMR_PROC_FUNC handler; UINT32 period; - UINT32 cpuId; + UINT32 cpuid; BOOL swtmrUsed; } SwtmrDebugData; diff --git a/kernel/base/misc/swtmr_shellcmd.c b/kernel/base/misc/swtmr_shellcmd.c index 80170c8d..f9fcb3f3 100644 --- a/kernel/base/misc/swtmr_shellcmd.c +++ b/kernel/base/misc/swtmr_shellcmd.c @@ -116,8 +116,8 @@ STATIC VOID OsSwtmrTimeInfoShow(VOID) UINT8 mode; SwtmrDebugData data; - PRINTK("SwtmrID CpuId Mode Period(us) WaitTime(us) WaitMax(us) RTime(us) RTimeMax(us) ReTime(us)" - " ReTimeMax(us) RunCount Handler\n"); + PRINTK("SwtmrID Cpuid Mode Period(us) WaitTime(us) WaitMax(us) RTime(us) RTimeMax(us) ReTime(us)" + " ReTimeMax(us) RunCount LostNum Handler\n"); for (UINT32 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) { if (!OsSwtmrDebugDataUsed(index)) { continue; @@ -128,15 +128,16 @@ STATIC VOID OsSwtmrTimeInfoShow(VOID) break; } - UINT64 waitTime = ((data.waitTime / data.waitCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; - UINT64 waitTimeMax = (data.waitTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; - UINT64 runTime = ((data.runTime / data.runCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; - UINT64 runTimeMax = (data.runTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; - UINT64 readyTime = ((data.readyTime / data.runCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; - UINT64 readyTimeMax = (data.readyTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; - PRINTK("%4u%10u%7s%14u%13llu%12llu%10llu%13llu%10llu%14llu%15llu%#12x\n", - index, data.cpuId, g_shellSwtmrMode[mode], data.period * OS_US_PER_TICK, waitTime, waitTimeMax, - runTime, runTimeMax, readyTime, readyTimeMax, data.runCount, data.handler); + SwtmrDebugBase *base = &data.base; + UINT64 waitTime = ((base->waitTime / base->waitCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 waitTimeMax = (base->waitTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 runTime = ((base->runTime / base->runCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 runTimeMax = (base->runTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 readyTime = ((base->readyTime / base->runCount) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + UINT64 readyTimeMax = (base->readyTimeMax * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + PRINTK("%4u%10u%7s%14u%13llu%12llu%10llu%13llu%10llu%14llu%15llu%11u%#12x\n", + index, data.cpuid, g_shellSwtmrMode[mode], data.period * OS_US_PER_TICK, waitTime, waitTimeMax, + runTime, runTimeMax, readyTime, readyTimeMax, base->runCount, base->times, data.handler); } } #endif diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c index 622c8fe6..20758754 100644 --- a/kernel/base/sched/sched_sq/los_sched.c +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -59,7 +59,6 @@ #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) @@ -133,7 +132,7 @@ UINT32 OsShellShowTickRespo(VOID) (VOID)memset_s((CHAR *)OsSchedDebugGet(), tickSize, 0, tickSize); for (cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { SchedRunQue *rq = OsSchedRunQueByID(cpu); - sortLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->taskSortLink) + OsGetSortLinkNodeNum(&rq->swtmrSortLink); + sortLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->taskSortLink); } SCHEDULER_UNLOCK(intSave); @@ -159,13 +158,6 @@ UINT32 OsShellShowTickRespo(VOID) (VOID)LOS_MemFree(m_aucSysMem1, schedDebug); return LOS_OK; } - -#else - -UINT32 OsShellShowTickRespo(VOID) -{ - return LOS_NOK; -} #endif #ifdef LOSCFG_SCHED_DEBUG @@ -175,6 +167,7 @@ UINT32 OsShellShowSchedParam(VOID) UINT64 averTimeSlice; UINT64 averSchedWait; UINT64 averPendTime; + UINT32 taskLinkNum[LOSCFG_KERNEL_CORE_NUM]; UINT32 intSave; UINT32 size = g_taskMaxNum * sizeof(LosTaskCB); LosTaskCB *taskCBArray = LOS_MemAlloc(m_aucSysMem1, size); @@ -184,7 +177,16 @@ UINT32 OsShellShowSchedParam(VOID) SCHEDULER_LOCK(intSave); (VOID)memcpy_s(taskCBArray, size, g_taskCBArray, size); + for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { + SchedRunQue *rq = OsSchedRunQueByID(cpu); + taskLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->taskSortLink); + } SCHEDULER_UNLOCK(intSave); + + for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { + PRINTK("cpu: %u Task SortMax: %u\n", cpu, taskLinkNum[cpu]); + } + PRINTK(" Tid AverRunTime(us) SwitchCount AverTimeSlice(us) TimeSliceCount AverReadyWait(us) " "AverPendTime(us) TaskName \n"); for (UINT32 tid = 0; tid < g_taskMaxNum; tid++) { @@ -228,13 +230,6 @@ UINT32 OsShellShowSchedParam(VOID) return LOS_OK; } - -#else - -UINT32 OsShellShowSchedParam(VOID) -{ - return LOS_NOK; -} #endif STATIC INLINE VOID TimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) @@ -259,28 +254,12 @@ STATIC INLINE VOID TimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) #endif } -STATIC INLINE UINT64 GetNextExpireTime(SchedRunQue *rq, UINT64 startTime, UINT32 tickPrecision) -{ - SortLinkAttribute *taskHeader = &rq->taskSortLink; - SortLinkAttribute *swtmrHeader = &rq->swtmrSortLink; - - LOS_SpinLock(&taskHeader->spinLock); - UINT64 taskExpireTime = OsGetSortLinkNextExpireTime(taskHeader, startTime, tickPrecision); - LOS_SpinUnlock(&taskHeader->spinLock); - - LOS_SpinLock(&swtmrHeader->spinLock); - UINT64 swtmrExpireTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime, tickPrecision); - LOS_SpinUnlock(&swtmrHeader->spinLock); - - return (taskExpireTime < swtmrExpireTime) ? taskExpireTime : swtmrExpireTime; -} - STATIC INLINE VOID SchedSetNextExpireTime(UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) { SchedRunQue *rq = OsSchedRunQue(); BOOL isTimeSlice = FALSE; UINT64 currTime = OsGetCurrSchedTimeCycle(); - UINT64 nextExpireTime = GetNextExpireTime(rq, currTime, OS_TICK_RESPONSE_PRECISION); + UINT64 nextExpireTime = OsGetSortLinkNextExpireTime(&rq->taskSortLink, currTime, OS_TICK_RESPONSE_PRECISION); rq->schedFlag &= ~INT_PEND_TICK; if (rq->responseID == oldResponseID) { @@ -496,7 +475,7 @@ VOID OsSchedTaskExit(LosTaskCB *taskCB) } if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { - OsSchedDeTaskFromTimeList(&taskCB->sortList); + OsSchedDeTaskFromTimeList(taskCB); taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); } } @@ -512,11 +491,10 @@ VOID OsSchedYield(VOID) OsSchedResched(); } -VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick) +VOID OsSchedDelay(LosTaskCB *runTask, UINT64 waitTime) { - OsSchedTaskDeQueue(runTask); runTask->taskStatus |= OS_TASK_STATUS_DELAY; - runTask->waitTimes = tick; + runTask->waitTime = waitTime; OsSchedResched(); } @@ -530,7 +508,7 @@ UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 ticks, BOOL needSched) if (ticks != LOS_WAIT_FOREVER) { runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME; - runTask->waitTimes = ticks; + runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks); } if (needSched == TRUE) { @@ -550,7 +528,7 @@ VOID OsSchedTaskWake(LosTaskCB *resumedTask) resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { - OsSchedDeTaskFromTimeList(&resumedTask->sortList); + OsSchedDeTaskFromTimeList(resumedTask); resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; } @@ -625,7 +603,7 @@ STATIC VOID SchedFreezeTask(LosTaskCB *taskCB) } responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); - OsSchedDeTaskFromTimeList(&taskCB->sortList); + OsSchedDeTaskFromTimeList(taskCB); SET_SORTLIST_VALUE(&taskCB->sortList, responseTime); taskCB->taskStatus |= OS_TASK_FLAG_FREEZE; return; @@ -634,7 +612,6 @@ STATIC VOID SchedFreezeTask(LosTaskCB *taskCB) STATIC VOID SchedUnfreezeTask(LosTaskCB *taskCB) { UINT64 currTime, responseTime; - UINT32 remainTick; if (!(taskCB->taskStatus & OS_TASK_FLAG_FREEZE)) { return; @@ -644,8 +621,7 @@ STATIC VOID SchedUnfreezeTask(LosTaskCB *taskCB) currTime = OsGetCurrSchedTimeCycle(); responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); if (responseTime > currTime) { - remainTick = ((responseTime - currTime) + OS_CYCLE_PER_TICK - 1) / OS_CYCLE_PER_TICK; - OsSchedAddTask2TimeList(&taskCB->sortList, currTime, remainTick); + OsSchedAddTask2TimeList(taskCB, responseTime); return; } @@ -687,97 +663,6 @@ BOOL OsSchedResume(LosTaskCB *taskCB) return needSched; } -STATIC INLINE BOOL SchedScanSwtmrTimeList(SchedRunQue *rq) -{ - BOOL needSched = FALSE; - SortLinkAttribute* swtmrSortLink = &rq->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(&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; - } - - 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; - if (SchedSwtmrRunQueFind(swtmrSortLink, checkFunc, arg)) { - return TRUE; - } - } - return FALSE; -} - STATIC INLINE VOID SchedWakePendTimeTask(UINT64 currTime, LosTaskCB *taskCB, BOOL *needSchedule) { #ifndef LOSCFG_SCHED_DEBUG @@ -853,14 +738,9 @@ STATIC INLINE BOOL SchedScanTaskTimeList(SchedRunQue *rq) VOID OsSchedTick(VOID) { SchedRunQue *rq = OsSchedRunQue(); - BOOL needSched = FALSE; if (rq->responseID == OS_INVALID_VALUE) { - - needSched |= SchedScanSwtmrTimeList(rq); - needSched |= SchedScanTaskTimeList(rq); - - if (needSched) { + if (SchedScanTaskTimeList(rq)) { LOS_MpSchedule(OS_MP_CPU_ALL); rq->schedFlag |= INT_PEND_RESCH; } @@ -892,18 +772,10 @@ VOID OsSchedRunQueInit(VOID) 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(); @@ -975,9 +847,7 @@ VOID OsSchedStart(VOID) SCHEDULER_LOCK(intSave); - if (cpuid == 0) { - OsTickStart(); - } + OsTickStart(); SchedRunQue *rq = OsSchedRunQue(); LosTaskCB *newTask = GetTopTask(rq); @@ -995,7 +865,7 @@ VOID OsSchedStart(VOID) newTask->startTime = OsGetCurrSchedTimeCycle(); - SchedSwtmrResponseTimeReset(rq, newTask->startTime); + OsSwtmrResponseTimeReset(newTask->startTime); /* System start schedule */ OS_SCHEDULER_SET(cpuid); @@ -1078,7 +948,7 @@ STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) TimeSliceUpdate(runTask, newTask->startTime); if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) { - OsSchedAddTask2TimeList(&runTask->sortList, runTask->startTime, runTask->waitTimes); + OsSchedAddTask2TimeList(runTask, runTask->startTime + runTask->waitTime); } } diff --git a/kernel/base/sched/sched_sq/los_sortlink.c b/kernel/base/sched/sched_sq/los_sortlink.c index af5d1592..ffad8838 100644 --- a/kernel/base/sched/sched_sq/los_sortlink.c +++ b/kernel/base/sched/sched_sq/los_sortlink.c @@ -82,21 +82,30 @@ VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 response node->cpuid = idleCpu; #endif LOS_SpinUnlock(&head->spinLock); +} -#ifdef LOSCFG_KERNEL_SMP - if (idleCpu != ArchCurrCpuid()) { - LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu)); +VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node) +{ + LOS_SpinLock(&head->spinLock); + if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { + OsDeleteNodeSortLink(head, node); } -#endif + LOS_SpinUnlock(&head->spinLock); } -VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node) +UINT32 OsSortLinkAdjustNodeResponseTime(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime) { + UINT32 ret = LOS_NOK; + LOS_SpinLock(&head->spinLock); if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { OsDeleteNodeSortLink(head, node); + SET_SORTLIST_VALUE(node, responseTime); + AddNode2SortLink(head, node); + ret = LOS_OK; } LOS_SpinUnlock(&head->spinLock); + return ret; } UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList) diff --git a/kernel/extended/cpup/los_cpup.c b/kernel/extended/cpup/los_cpup.c index 51a3641d..2b9c31cf 100644 --- a/kernel/extended/cpup/los_cpup.c +++ b/kernel/extended/cpup/los_cpup.c @@ -254,7 +254,7 @@ VOID OsCpupCycleEndStart(UINT32 runTaskID, UINT32 newTaskID) OsCpupBase *newTaskCpup = (OsCpupBase *)&(OS_TCB_FROM_TID(newTaskID)->taskCpup); OsCpupBase *processCpup = OS_PCB_FROM_PID(runTask->processID)->processCpup; UINT64 cpuCycle, cycleIncrement; - UINT16 cpuID = ArchCurrCpuid(); + UINT16 cpuid = ArchCurrCpuid(); if (cpupInitFlg == 0) { return; @@ -264,8 +264,8 @@ VOID OsCpupCycleEndStart(UINT32 runTaskID, UINT32 newTaskID) if (runTaskCpup->startTime != 0) { cycleIncrement = cpuCycle - runTaskCpup->startTime; #ifdef LOSCFG_CPUP_INCLUDE_IRQ - cycleIncrement -= timeInIrqSwitch[cpuID]; - timeInIrqSwitch[cpuID] = 0; + cycleIncrement -= timeInIrqSwitch[cpuid]; + timeInIrqSwitch[cpuid] = 0; #endif runTaskCpup->allTime += cycleIncrement; if (processCpup != NULL) { @@ -275,7 +275,7 @@ VOID OsCpupCycleEndStart(UINT32 runTaskID, UINT32 newTaskID) } newTaskCpup->startTime = cpuCycle; - runningTasks[cpuID] = newTaskID; + runningTasks[cpuid] = newTaskID; } LITE_OS_SEC_TEXT_MINOR STATIC VOID OsCpupGetPos(UINT16 mode, UINT16 *curPosPointer, UINT16 *prePosPointer) @@ -524,17 +524,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllProcessAndTaskCpuUsageUnsafe(UINT16 mode, } #ifdef LOSCFG_CPUP_INCLUDE_IRQ -LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(UINT16 cpuId) +LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(UINT16 cpuid) { UINT32 high; UINT32 low; LOS_GetCpuCycle(&high, &low); - cpupIntTimeStart[cpuId] = ((UINT64)high << HIGH_BITS) + low; + cpupIntTimeStart[cpuid] = ((UINT64)high << HIGH_BITS) + low; return; } -LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT16 cpuId, UINT32 intNum) +LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT16 cpuid, UINT32 intNum) { UINT32 high; UINT32 low; @@ -543,11 +543,11 @@ LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT16 cpuId, UINT32 intNum) LOS_GetCpuCycle(&high, &low); intTimeEnd = ((UINT64)high << HIGH_BITS) + low; - OsIrqCpupCB *irqCb = &g_irqCpup[(intNum * LOSCFG_KERNEL_CORE_NUM) + cpuId]; + OsIrqCpupCB *irqCb = &g_irqCpup[(intNum * LOSCFG_KERNEL_CORE_NUM) + cpuid]; irqCb->id = intNum; irqCb->status = OS_CPUP_USED; - usedTime = intTimeEnd - cpupIntTimeStart[cpuId]; - timeInIrqSwitch[cpuId] += usedTime; + usedTime = intTimeEnd - cpupIntTimeStart[cpuid]; + timeInIrqSwitch[cpuid] += usedTime; irqCb->cpup.allTime += usedTime; if (irqCb->count <= 100) { /* Take 100 samples */ irqCb->allTime += usedTime; diff --git a/kernel/extended/trace/los_trace.c b/kernel/extended/trace/los_trace.c index 959b2578..d7d34eae 100644 --- a/kernel/extended/trace/los_trace.c +++ b/kernel/extended/trace/los_trace.c @@ -101,7 +101,7 @@ STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR id frame->eventType = eventType; #ifdef LOSCFG_TRACE_FRAME_CORE_MSG - frame->core.cpuId = ArchCurrCpuid(); + frame->core.cpuid = ArchCurrCpuid(); frame->core.hwiActive = OS_INT_ACTIVE ? TRUE : FALSE; frame->core.taskLockCnt = MIN(OsSchedLockCountGet(), 0xF); /* taskLockCnt is 4 bits, max value = 0xF */ frame->core.paramCount = paramCount; diff --git a/kernel/extended/trace/trace_offline.c b/kernel/extended/trace/trace_offline.c index 09a804ca..ad80087c 100644 --- a/kernel/extended/trace/trace_offline.c +++ b/kernel/extended/trace/trace_offline.c @@ -157,7 +157,7 @@ STATIC VOID OsTraceInfoEventTitle(VOID) PRINTK("Index Time(cycles) EventType CurPid CurTask Identity "); #ifdef LOSCFG_TRACE_FRAME_CORE_MSG - PRINTK("cpuId hwiActive taskLockCnt "); + PRINTK("cpuid hwiActive taskLockCnt "); #endif #ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT PRINTK("eventCount "); @@ -192,7 +192,7 @@ STATIC VOID OsTraceInfoEventData(VOID) */ taskLockCnt -= 1; #endif - PRINTK("%-11u %-11u %-11u", frame->core.cpuId, frame->core.hwiActive, taskLockCnt); + PRINTK("%-11u %-11u %-11u", frame->core.cpuid, frame->core.hwiActive, taskLockCnt); #endif #ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT PRINTK("%-11u", frame->eventCount); diff --git a/kernel/include/los_trace.h b/kernel/include/los_trace.h index f0c6948d..3d9652c9 100644 --- a/kernel/include/los_trace.h +++ b/kernel/include/los_trace.h @@ -245,7 +245,7 @@ typedef struct { UINTPTR identity; /**< subject of the event description */ #ifdef LOSCFG_TRACE_FRAME_CORE_MSG struct CoreStatus { - UINT32 cpuId : 8, /**< cpuid */ + UINT32 cpuid : 8, /**< cpuid */ hwiActive : 4, /**< whether is in hwi response */ taskLockCnt : 4, /**< task lock count */ paramCount : 4, /**< event frame params' number */ diff --git a/testsuites/kernel/include/osTest.h b/testsuites/kernel/include/osTest.h index e4ec630e..88dbe464 100644 --- a/testsuites/kernel/include/osTest.h +++ b/testsuites/kernel/include/osTest.h @@ -343,7 +343,7 @@ extern void TestSystemInit(void); extern void TEST_DT_COMMON(void); extern VOID dprintf(const char *fmt, ...); -extern UINT32 OsSwtmrTaskIdByCpuId(UINT16 cpuId); +extern UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid); #define BIG_FD 512 typedef struct testrunParam { diff --git a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c index 07ff3f27..eed2544c 100644 --- a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c +++ b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_081.c @@ -49,7 +49,7 @@ static UINT32 Testcase(void) ret = LOS_TaskSuspend(gTestIdleTaskID); ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); - gTestSwtmrTaskID = OsSwtmrTaskIdByCpuId(cpuid); + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); ret = LOS_TaskSuspend(gTestSwtmrTaskID); ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); diff --git a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c index 7cad4642..ca48b5da 100644 --- a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c +++ b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_114.c @@ -49,7 +49,7 @@ static UINT32 Testcase(void) ret = LOS_TaskDelete(gTestIdleTaskID); ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); - gTestSwtmrTaskID = OsSwtmrTaskIdByCpuId(cpuid); + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); ret = LOS_TaskDelete(gTestSwtmrTaskID); ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); diff --git a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c index 2c1d8691..b5b7d165 100644 --- a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c +++ b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_115.c @@ -44,7 +44,7 @@ static UINT32 Testcase(void) UINT32 gTestSwtmrTaskID; UINT32 cpuid = (ArchCurrCpuid() + 1) % (LOSCFG_KERNEL_CORE_NUM); - gTestSwtmrTaskID = OsSwtmrTaskIdByCpuId(cpuid); + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); ret = LOS_TaskDelete(gTestSwtmrTaskID); ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK, ret); diff --git a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c index 32236761..9bf825d2 100644 --- a/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c +++ b/testsuites/kernel/sample/kernel_base/core/task/smp/It_smp_los_task_126.c @@ -54,7 +54,7 @@ static void HwiF01(void) LOS_AtomicInc(&g_testCount); - gTestSwtmrTaskID = OsSwtmrTaskIdByCpuId(cpuid); + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); ret = LOS_TaskDelete(gTestSwtmrTaskID); ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); 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 a0c53958..ef190e86 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 @@ -49,7 +49,7 @@ static void HwiF01(void) ret = LOS_TaskDelete(gTestIdleTaskID); ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); - gTestSwtmrTaskID = OsSwtmrTaskIdByCpuId(cpuid); + gTestSwtmrTaskID = OsSwtmrTaskIDGetByCpuid(cpuid); ret = LOS_TaskDelete(gTestSwtmrTaskID); ICUNIT_ASSERT_EQUAL_VOID(ret, LOS_ERRNO_TSK_YIELD_IN_INT, ret); -- GitLab