diff --git a/arch/arm/arm/include/hal_timer.h b/arch/arm/arm/include/hal_timer.h index fd218f9a4dcd239617770de8925eec900884e2d1..667188bc5e0b927490d46629fe287c524258a628 100644 --- a/arch/arm/arm/include/hal_timer.h +++ b/arch/arm/arm/include/hal_timer.h @@ -46,7 +46,7 @@ extern VOID HalClockInit(VOID); extern UINT64 HalClockGetCycles(VOID); extern VOID HalDelayUs(UINT32 usecs); extern UINT32 HalClockGetTickTimerCycles(VOID); -extern VOID HalClockTickTimerReload(UINT64 cycles); +extern UINT64 HalClockTickTimerReload(UINT64 cycles); extern UINT32 HrtimersInit(VOID); extern VOID HrtimerClockIrqClear(VOID); diff --git a/arch/arm/arm/src/arm_generic_timer.c b/arch/arm/arm/src/arm_generic_timer.c index e3a732fae671a370080e2b0d31d676429d964b34..bf0b01a23bcd9bc15264cd068c70c103f8191142 100644 --- a/arch/arm/arm/src/arm_generic_timer.c +++ b/arch/arm/arm/src/arm_generic_timer.c @@ -31,7 +31,6 @@ #include "los_hw_pri.h" #include "los_tick_pri.h" -#include "los_sched_pri.h" #include "los_sys_pri.h" #include "gic_common.h" @@ -139,11 +138,6 @@ LITE_OS_SEC_TEXT_INIT VOID HalClockInit(VOID) LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID) { - UINT32 ret = OsSchedSetTickTimerType(64); /* 64 bit tick timer */ - if (ret != LOS_OK) { - return; - } - HalIrqUnmask(OS_TICK_INT_NUM); /* triggle the first tick */ @@ -175,7 +169,7 @@ UINT32 HalClockGetTickTimerCycles(VOID) return (UINT32)((cval > cycles) ? (cval - cycles) : 0); } -VOID HalClockTickTimerReload(UINT64 cycles) +UINT64 HalClockTickTimerReload(UINT64 cycles) { HalIrqMask(OS_TICK_INT_NUM); HalIrqClear(OS_TICK_INT_NUM); @@ -185,4 +179,5 @@ VOID HalClockTickTimerReload(UINT64 cycles) TimerCtlWrite(1); HalIrqUnmask(OS_TICK_INT_NUM); + return cycles; } diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index dde50c6694a59b89df676331767ab0035071f43e..455d0e5717e96417f9d802b4b6471584e4170f87 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -246,7 +246,7 @@ STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, UINT64 currTime, SWTMR_CTRL_ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) { Percpu *cpu = OsPercpuGet(); - SortLinkAttribute* swtmrSortLink = &OsPercpuGet()->swtmrSortLink; + SortLinkAttribute* swtmrSortLink = &cpu->swtmrSortLink; LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; /* @@ -268,7 +268,7 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) swtmr->startTime = GET_SORTLIST_VALUE(sortList); OsDeleteNodeSortLink(swtmrSortLink, sortList); LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - + OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr); OsWakePendTimeSwtmr(cpu, currTime, swtmr); @@ -283,6 +283,33 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); } +LITE_OS_SEC_TEXT VOID OsSwtmrResponseTimeReset(UINT64 startTime) +{ + 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(startTime, swtmr); + SWTMR_UNLOCK(intSave); + + LOS_SpinLock(&cpu->swtmrSortLinkSpin); + listNext = listNext->pstNext; + } + LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); +} + /* * Description: Get next timeout * Return : Count of the Timer list diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index 9270aa78b443f99cca9f0abdf9728a483da129f0..0df3005b84d66305b6e2116a21f50d28bb059989 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -52,15 +52,9 @@ extern "C" { extern UINT32 g_taskScheduled; typedef BOOL (*SchedScan)(VOID); -extern UINT64 g_sysSchedStartTime; - STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) { - if (g_sysSchedStartTime != OS_64BIT_MAX) { - return (HalClockGetCycles() - g_sysSchedStartTime); - } - - return 0; + return HalClockGetCycles(); } STATIC INLINE VOID OsSchedIrqUpdateUsedTime(VOID) @@ -156,8 +150,6 @@ STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave) LOS_IntRestore(intSave); } -extern UINT32 OsSchedSetTickTimerType(UINT32 timerType); - extern VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask); extern UINT32 OsSchedSwtmrScanRegister(SchedScan func); diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h index a77be1eb5550a19350d2352bb0e05daa71589e7e..caa344c590856357d604992a62b50b44591631d8 100644 --- a/kernel/base/include/los_sortlink_pri.h +++ b/kernel/base/include/los_sortlink_pri.h @@ -64,9 +64,31 @@ typedef struct { #define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->responseTime = (value)) #define GET_SORTLIST_VALUE(sortList) (((SortLinkList *)(sortList))->responseTime) -extern UINT64 OsGetNextExpireTime(UINT64 startTime); +STATIC INLINE VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) +{ + LOS_ListDelete(&sortList->sortLinkNode); + SET_SORTLIST_VALUE(sortList, OS_SORT_LINK_INVALID_TIME); + sortLinkHeader->nodeNum--; +} + +STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime, UINT32 tickPrecision) +{ + LOS_DL_LIST *head = &sortHeader->sortLink; + LOS_DL_LIST *list = head->pstNext; + + if (LOS_ListEmpty(head)) { + return OS_SORT_LINK_INVALID_TIME - tickPrecision; + } + + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); + if (listSorted->responseTime <= (startTime + tickPrecision)) { + return startTime + tickPrecision; + } + + return listSorted->responseTime; +} + extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader); -extern VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList); extern VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type); extern VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type); extern UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList); diff --git a/kernel/base/include/los_swtmr_pri.h b/kernel/base/include/los_swtmr_pri.h index bfbba009f96e7ae561ded52cc1aada6a96afa787..31651f89617b96cb7d6a6cda8cf44db7c2d26e5a 100644 --- a/kernel/base/include/los_swtmr_pri.h +++ b/kernel/base/include/los_swtmr_pri.h @@ -104,6 +104,7 @@ extern VOID OsSwtmrScan(VOID); extern UINT32 OsSwtmrInit(VOID); extern VOID OsSwtmrTask(VOID); extern VOID OsSwtmrRecycle(UINT32 processID); +extern VOID OsSwtmrResponseTimeReset(UINT64 startTime); extern SPIN_LOCK_S g_swtmrSpin; #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c index effca28bac6359f34b41bd590d912f6b0645c56c..edc85900c598eef5958b46661b3d8f8297134981 100644 --- a/kernel/base/sched/sched_sq/los_sched.c +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -32,6 +32,7 @@ #include "los_sched_pri.h" #include "los_hw_pri.h" #include "los_task_pri.h" +#include "los_swtmr_pri.h" #include "los_process_pri.h" #include "los_arch_mmu.h" #include "los_hook.h" @@ -75,8 +76,6 @@ typedef struct { } Sched; STATIC Sched *g_sched = NULL; -STATIC UINT64 g_schedTickMaxResponseTime; -UINT64 g_sysSchedStartTime = OS_64BIT_MAX; #ifdef LOSCFG_SCHED_TICK_DEBUG #define OS_SCHED_DEBUG_DATA_NUM 1000 @@ -237,30 +236,6 @@ UINT32 OsShellShowSchedParam(VOID) } #endif -UINT32 OsSchedSetTickTimerType(UINT32 timerType) -{ - switch (timerType) { - case 32: /* 32 bit timer */ - g_schedTickMaxResponseTime = OS_32BIT_MAX; - break; - case 64: /* 64 bit timer */ - g_schedTickMaxResponseTime = OS_64BIT_MAX; - break; - default: - PRINT_ERR("Unsupported Tick Timer type, The system only supports 32 and 64 bit tick timers\n"); - return LOS_NOK; - } - - return LOS_OK; -} - -STATIC VOID OsSchedSetStartTime(UINT64 currCycle) -{ - if (g_sysSchedStartTime == OS_64BIT_MAX) { - g_sysSchedStartTime = currCycle; - } -} - STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) { LOS_ASSERT(currTime >= taskCB->startTime); @@ -283,54 +258,29 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) #endif } -STATIC INLINE VOID OsSchedTickReload(Percpu *currCpu, UINT64 nextResponseTime, UINT32 responseID, BOOL isTimeSlice) +STATIC INLINE UINT64 GetNextExpireTime(Percpu *cpu, UINT64 startTime, UINT32 tickPrecision) { - UINT64 currTime, nextExpireTime; - UINT32 usedTime; + SortLinkAttribute *taskHeader = &cpu->taskSortLink; + SortLinkAttribute *swtmrHeader = &cpu->swtmrSortLink; - currTime = OsGetCurrSchedTimeCycle(); - if (currCpu->tickStartTime != 0) { - usedTime = currTime - currCpu->tickStartTime; - currCpu->tickStartTime = 0; - } else { - usedTime = 0; - } - - if ((nextResponseTime > usedTime) && ((nextResponseTime - usedTime) > OS_TICK_RESPONSE_PRECISION)) { - nextResponseTime -= usedTime; - } else { - nextResponseTime = OS_TICK_RESPONSE_PRECISION; - } + LOS_SpinLock(&cpu->taskSortLinkSpin); + UINT64 taskExpireTime = OsGetSortLinkNextExpireTime(taskHeader, startTime, tickPrecision); + LOS_SpinUnlock(&cpu->taskSortLinkSpin); - nextExpireTime = currTime + nextResponseTime; - if (nextExpireTime >= currCpu->responseTime) { - return; - } + LOS_SpinLock(&cpu->swtmrSortLinkSpin); + UINT64 swtmrExpireTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime, tickPrecision); + LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - if (isTimeSlice) { - /* The expiration time of the current system is the thread's slice expiration time */ - currCpu->responseID = responseID; - } else { - currCpu->responseID = OS_INVALID_VALUE; - } - currCpu->responseTime = nextExpireTime; - HalClockTickTimerReload(nextResponseTime); - -#ifdef LOSCFG_SCHED_TICK_DEBUG - SchedTickDebug *schedDebug = &g_schedTickDebug[ArchCurrCpuid()]; - if (schedDebug->index < OS_SCHED_DEBUG_DATA_NUM) { - schedDebug->setTickCount++; - } -#endif + return (taskExpireTime < swtmrExpireTime) ? taskExpireTime : swtmrExpireTime; } STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) { - UINT64 nextExpireTime = OsGetNextExpireTime(startTime); Percpu *currCpu = OsPercpuGet(); - UINT64 nextResponseTime; + UINT64 nextResponseTime = 0; BOOL isTimeSlice = FALSE; + UINT64 nextExpireTime = GetNextExpireTime(currCpu, startTime, OS_TICK_RESPONSE_PRECISION); currCpu->schedFlag &= ~INT_PEND_TICK; if (currCpu->responseID == oldResponseID) { @@ -346,19 +296,35 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, isTimeSlice = TRUE; } - if ((currCpu->responseTime > nextExpireTime) && - ((currCpu->responseTime - nextExpireTime) >= OS_TICK_RESPONSE_PRECISION)) { - nextResponseTime = nextExpireTime - startTime; - if (nextResponseTime > g_schedTickMaxResponseTime) { - nextResponseTime = g_schedTickMaxResponseTime; - } - } else { - /* There is no point earlier than the current expiration date */ - currCpu->tickStartTime = 0; + if ((currCpu->responseTime <= nextExpireTime) || + ((currCpu->responseTime - nextExpireTime) < OS_TICK_RESPONSE_PRECISION)) { return; } - OsSchedTickReload(currCpu, nextResponseTime, responseID, isTimeSlice); + 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; + } else { + currCpu->responseID = OS_INVALID_VALUE; + } + + currCpu->responseTime = currTime + HalClockTickTimerReload(nextResponseTime); + +#ifdef LOSCFG_SCHED_TICK_DEBUG + SchedTickDebug *schedDebug = &g_schedTickDebug[ArchCurrCpuid()]; + if (schedDebug->index < OS_SCHED_DEBUG_DATA_NUM) { + schedDebug->setTickCount++; + } +#endif } VOID OsSchedUpdateExpireTime(UINT64 startTime) @@ -843,9 +809,7 @@ VOID OsSchedTick(VOID) Sched *sched = g_sched; Percpu *currCpu = OsPercpuGet(); BOOL needSched = FALSE; - LosTaskCB *runTask = OsCurrTaskGet(); - currCpu->tickStartTime = runTask->irqStartTime; if (currCpu->responseID == OS_INVALID_VALUE) { if (sched->swtmrScan != NULL) { (VOID)sched->swtmrScan(); @@ -970,6 +934,8 @@ VOID OsSchedStart(VOID) UINT32 cpuid = ArchCurrCpuid(); UINT32 intSave; + PRINTK("cpu %d entering scheduler\n", cpuid); + SCHEDULER_LOCK(intSave); if (cpuid == 0) { @@ -983,9 +949,6 @@ VOID OsSchedStart(VOID) newProcess->processStatus |= OS_PROCESS_STATUS_RUNNING; newProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(newProcess->processStatus); - OsSchedSetStartTime(HalClockGetCycles()); - newTask->startTime = OsGetCurrSchedTimeCycle(); - #ifdef LOSCFG_KERNEL_SMP /* * attention: current cpu needs to be set, in case first task deletion @@ -996,13 +959,15 @@ VOID OsSchedStart(VOID) OsCurrTaskSet((VOID *)newTask); + newTask->startTime = OsGetCurrSchedTimeCycle(); + + OsSwtmrResponseTimeReset(newTask->startTime); + /* System start schedule */ OS_SCHEDULER_SET(cpuid); OsPercpuGet()->responseID = OS_INVALID; OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, newTask->startTime + newTask->timeSlice, OS_INVALID); - - PRINTK("cpu %d entering scheduler\n", cpuid); OsTaskContextLoad(newTask); } diff --git a/kernel/base/sched/sched_sq/los_sortlink.c b/kernel/base/sched/sched_sq/los_sortlink.c index 91158926ea1f4b9ec739c90452e97ed23335d71c..b193b6dfad9afddc8bcb62d510b408dee8bc28a8 100644 --- a/kernel/base/sched/sched_sq/los_sortlink.c +++ b/kernel/base/sched/sched_sq/los_sortlink.c @@ -77,30 +77,6 @@ STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLin } while (1); } -VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) -{ - LOS_ListDelete(&sortList->sortLinkNode); - SET_SORTLIST_VALUE(sortList, OS_SORT_LINK_INVALID_TIME); - sortLinkHeader->nodeNum--; -} - -STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime) -{ - LOS_DL_LIST *head = &sortHeader->sortLink; - LOS_DL_LIST *list = head->pstNext; - - if (LOS_ListEmpty(head)) { - return OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; - } - - SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); - if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) { - return startTime + OS_TICK_RESPONSE_PRECISION; - } - - return listSorted->responseTime; -} - STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID) { Percpu *idleCpu = OsPercpuGetByID(0); @@ -127,7 +103,6 @@ STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID) VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type) { - UINT32 intSave; Percpu *cpu = NULL; SortLinkAttribute *sortLinkHeader = NULL; SPIN_LOCK_S *spinLock = NULL; @@ -150,7 +125,7 @@ VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, Sort LOS_Panic("Sort link type error : %u\n", type); } - LOS_SpinLockSave(spinLock, &intSave); + LOS_SpinLock(spinLock); SET_SORTLIST_VALUE(node, startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK); OsAddNode2SortLink(sortLinkHeader, node); #ifdef LOSCFG_KERNEL_SMP @@ -159,12 +134,11 @@ VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, Sort LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu)); } #endif - LOS_SpinUnlockRestore(spinLock, intSave); + LOS_SpinUnlock(spinLock); } VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type) { - UINT32 intSave; #ifdef LOSCFG_KERNEL_SMP Percpu *cpu = OsPercpuGetByID(node->cpuid); #else @@ -183,29 +157,11 @@ VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type) LOS_Panic("Sort link type error : %u\n", type); } - LOS_SpinLockSave(spinLock, &intSave); + LOS_SpinLock(spinLock); if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { OsDeleteNodeSortLink(sortLinkHeader, node); } - LOS_SpinUnlockRestore(spinLock, intSave); -} - -UINT64 OsGetNextExpireTime(UINT64 startTime) -{ - UINT32 intSave; - Percpu *cpu = OsPercpuGet(); - SortLinkAttribute *taskHeader = &cpu->taskSortLink; - SortLinkAttribute *swtmrHeader = &cpu->swtmrSortLink; - - LOS_SpinLockSave(&cpu->taskSortLinkSpin, &intSave); - UINT64 taskExpirTime = OsGetSortLinkNextExpireTime(taskHeader, startTime); - LOS_SpinUnlockRestore(&cpu->taskSortLinkSpin, intSave); - - LOS_SpinLockSave(&cpu->swtmrSortLinkSpin, &intSave); - UINT64 swtmrExpirTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime); - LOS_SpinUnlockRestore(&cpu->swtmrSortLinkSpin, intSave); - - return (taskExpirTime < swtmrExpirTime) ? taskExpirTime : swtmrExpirTime; + LOS_SpinUnlock(spinLock); } UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList) diff --git a/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp b/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp index 1eab1e2dc592c8f68680ce94e45360126e625c81..2900a1e10d9da966025d9c12889d16e73f1be5a6 100644 --- a/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp +++ b/testsuites/unittest/process/basic/process/smoke/process_test_001.cpp @@ -67,7 +67,7 @@ static int Testcase(VOID) ICUNIT_ASSERT_EQUAL(err, EINVAL, err); param.sched_priority = 15; // 15, set pthread priority. - ret = sched_setparam(20, ¶m); // 20, set the param. + ret = sched_setparam(60, ¶m); // 60, set the param. err = errno; ICUNIT_ASSERT_EQUAL(ret, -1, ret); ICUNIT_ASSERT_EQUAL(err, ESRCH, err);