From 8df3e8c96515a1907455a9bbc61426f43c803c62 Mon Sep 17 00:00:00 2001 From: zhushengle Date: Fri, 6 Aug 2021 12:48:00 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20tick=20=E5=8A=A8=E6=80=81=E5=8C=96?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E4=BC=98=E5=8C=96=EF=BC=8C=E6=B6=88=E9=99=A4?= =?UTF-8?q?=E4=B8=AD=E6=96=AD=E6=89=A7=E8=A1=8C=E6=97=B6=E9=97=B4=E5=AF=B9?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=80=BB=E4=BD=93=E6=97=B6=E9=97=B4=E7=9A=84?= =?UTF-8?q?=E5=BD=B1=E5=93=8D=EF=BC=8C=E4=BF=9D=E8=AF=81=E8=BD=AF=E4=BB=B6?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E5=99=A8=E7=9A=84=E5=93=8D=E5=BA=94=E7=B2=BE?= =?UTF-8?q?=E5=BA=A6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 方案描述: 1.周期软件定时器超时添加一个startTime字段,用于记录当前软件定时器的开始计时的时间, 在定时器响应时,开始时间修改为上一次响应的结束时间(消除了中断执行时间对软件定时器 的影响)。 2.在执行tick中断的过程当中,持有tick动态计算锁,保证在该过程中不会触发tick周期 的计算,在tick中断结束时统一计算设置。 --- 提升tick中断的执行效率 3.在设置tick周期时,减掉tick中断执行的时间,减小周期动态化带来的时间误差 4.新增LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI配置宏,用于配置tick中断的最小响应精度 Close #I43UQJ Signed-off-by: zhushengle Change-Id: Icd1159a1890046b13602b7a18dcd6234d5c61a89 --- kernel/base/BUILD.gn | 6 +- kernel/base/core/los_swtmr.c | 26 ++-- kernel/base/include/los_percpu_pri.h | 1 + kernel/base/include/los_sched_pri.h | 17 ++- kernel/base/include/los_sortlink_pri.h | 1 + kernel/base/misc/swtmr_shellcmd.c | 5 +- kernel/base/mp/los_mp.c | 2 +- kernel/base/sched/sched_sq/los_sched.c | 118 +++++++++++------- .../{core => sched/sched_sq}/los_sortlink.c | 31 +---- kernel/include/los_swtmr.h | 1 + platform/los_config.h | 16 +++ 11 files changed, 129 insertions(+), 95 deletions(-) rename kernel/base/{core => sched/sched_sq}/los_sortlink.c (91%) diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn index b231ed27..769e93ed 100644 --- a/kernel/base/BUILD.gn +++ b/kernel/base/BUILD.gn @@ -34,7 +34,6 @@ kernel_module(module_name) { sources = [ "core/los_bitmap.c", "core/los_process.c", - "core/los_sortlink.c", "core/los_swtmr.c", "core/los_sys.c", "core/los_task.c", @@ -68,6 +67,7 @@ kernel_module(module_name) { "mp/los_stat.c", "om/los_err.c", "sched/sched_sq/los_sched.c", + "sched/sched_sq/los_sortlink.c", "vm/los_vm_boot.c", "vm/los_vm_dump.c", "vm/los_vm_fault.c", @@ -83,9 +83,7 @@ kernel_module(module_name) { ] if (defined(LOSCFG_SHELL_CMD_DEBUG)) { - configs += [ - "$HDFTOPDIR:hdf_config" - ] + configs += [ "$HDFTOPDIR:hdf_config" ] } public_configs = [ ":public" ] diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index 765deb01..687c79e5 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -178,10 +178,9 @@ ERROR: * Description: Start Software Timer * Input : swtmr --- Need to start software timer */ -LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) +LITE_OS_SEC_TEXT VOID OsSwtmrStart(UINT64 currTime, SWTMR_CTRL_S *swtmr) { UINT32 ticks; - UINT64 currTime = OsGetCurrSchedTimeCycle(); if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || @@ -192,10 +191,8 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) } swtmr->ucState = OS_SWTMR_STATUS_TICKING; - OsAdd2SortLink(&swtmr->stSortList, currTime, ticks, OS_SORT_LINK_SWTMR); - if (OS_SCHEDULER_ACTIVE) { - OsSchedUpdateExpireTime(currTime); - } + OsAdd2SortLink(&swtmr->stSortList, swtmr->startTime, ticks, OS_SORT_LINK_SWTMR); + OsSchedUpdateExpireTime(currTime); return; } @@ -211,7 +208,7 @@ STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) swtmr->uwOwnerPid = 0; } -STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, SWTMR_CTRL_S *swtmr) +STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, UINT64 currTime, SWTMR_CTRL_S *swtmr) { LOS_SpinLock(&g_swtmrSpin); SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); @@ -236,7 +233,7 @@ STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, SWTMR_CTRL_S *swtmr) swtmr->ucState = OS_SWTMR_STATUS_CREATED; } else { swtmr->uwOverrun++; - OsSwtmrStart(swtmr); + OsSwtmrStart(currTime, swtmr); } LOS_SpinUnlock(&g_swtmrSpin); @@ -267,12 +264,12 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) UINT64 currTime = OsGetCurrSchedTimeCycle(); while (sortList->responseTime <= currTime) { sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); - OsDeleteNodeSortLink(swtmrSortLink, sortList); - 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); - OsWakePendTimeSwtmr(cpu, swtmr); + OsWakePendTimeSwtmr(cpu, currTime, swtmr); LOS_SpinLock(&cpu->swtmrSortLinkSpin); if (LOS_ListEmpty(listObject)) { @@ -305,9 +302,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) swtmr->ucState = OS_SWTMR_STATUS_CREATED; swtmr->uwOverrun = 0; - if (OS_SCHEDULER_ACTIVE) { - OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle()); - } + OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle()); } /* @@ -403,7 +398,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) OsSwtmrStop(swtmr); /* fall-through */ case OS_SWTMR_STATUS_CREATED: - OsSwtmrStart(swtmr); + swtmr->startTime = OsGetCurrSchedTimeCycle(); + OsSwtmrStart(swtmr->startTime, swtmr); break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; diff --git a/kernel/base/include/los_percpu_pri.h b/kernel/base/include/los_percpu_pri.h index 70662bf1..1f5aa828 100644 --- a/kernel/base/include/los_percpu_pri.h +++ b/kernel/base/include/los_percpu_pri.h @@ -57,6 +57,7 @@ typedef struct { SortLinkAttribute swtmrSortLink; /* swtmr sort link */ SPIN_LOCK_S swtmrSortLinkSpin; /* swtmr sort link spin lock */ UINT64 responseTime; /* Response time for current nuclear Tick interrupts */ + UINT64 tickStartTime; /* The time when the tick interrupt starts processing */ UINT32 responseID; /* The response ID of the current nuclear TICK interrupt */ UINTPTR runProcess; /* The address of the process control block pointer to which the current kernel is running */ diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index 8d45f1d2..698cf545 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -45,6 +45,10 @@ 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) + extern UINT32 g_taskScheduled; typedef BOOL (*SchedScan)(VOID); @@ -86,8 +90,9 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID) #define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) typedef enum { - INT_NO_RESCH = 0, /* no needs to schedule */ - INT_PEND_RESCH, /* pending schedule flag */ + 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 */ @@ -102,7 +107,7 @@ STATIC INLINE BOOL OsPreemptable(VOID) BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0); if (!preemptable) { /* Set schedule flag if preemption is disabled */ - OsPercpuGet()->schedFlag = INT_PEND_RESCH; + OsPercpuGet()->schedFlag |= INT_PEND_RESCH; } LOS_IntRestore(intSave); return preemptable; @@ -124,7 +129,7 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID) #endif if (!preemptable) { /* Set schedule flag if preemption is disabled */ - OsPercpuGet()->schedFlag = INT_PEND_RESCH; + OsPercpuGet()->schedFlag |= INT_PEND_RESCH; } return preemptable; @@ -139,8 +144,8 @@ 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_NO_RESCH; + if ((cpu->taskLockCnt == 0) && (cpu->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { + cpu->schedFlag &= ~INT_PEND_RESCH; LOS_IntRestore(intSave); LOS_Schedule(); return; diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h index 07a04d91..a77be1eb 100644 --- a/kernel/base/include/los_sortlink_pri.h +++ b/kernel/base/include/los_sortlink_pri.h @@ -62,6 +62,7 @@ typedef struct { #define OS_SORT_LINK_INVALID_TIME ((UINT64)-1) #define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->responseTime = (value)) +#define GET_SORTLIST_VALUE(sortList) (((SortLinkList *)(sortList))->responseTime) extern UINT64 OsGetNextExpireTime(UINT64 startTime); extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader); diff --git a/kernel/base/misc/swtmr_shellcmd.c b/kernel/base/misc/swtmr_shellcmd.c index 582704dd..dcb7b706 100644 --- a/kernel/base/misc/swtmr_shellcmd.c +++ b/kernel/base/misc/swtmr_shellcmd.c @@ -54,6 +54,9 @@ LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrStatus[][SWTMR_STRLEN] = { STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr) { + UINT32 ticks = 0; + (VOID)LOS_SwtmrTimeGet(swtmr->usTimerID, &ticks); + PRINTK("0x%08x " "%-7s " "%-6s " @@ -65,7 +68,7 @@ STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr) g_shellSwtmrStatus[swtmr->ucState], g_shellSwtmrMode[swtmr->ucMode], swtmr->uwInterval, - swtmr->uwCount, + ticks, swtmr->uwArg, swtmr->pfnHandler); } diff --git a/kernel/base/mp/los_mp.c b/kernel/base/mp/los_mp.c index 7bdce6ac..a465d52a 100644 --- a/kernel/base/mp/los_mp.c +++ b/kernel/base/mp/los_mp.c @@ -56,7 +56,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; + OsPercpuGet()->schedFlag |= INT_PEND_RESCH; } VOID OsMpHaltHandler(VOID) diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c index 73e73d67..57b48c99 100644 --- a/kernel/base/sched/sched_sq/los_sched.c +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -47,8 +47,6 @@ #include "los_stat_pri.h" #endif - - #define OS_32BIT_MAX 0xFFFFFFFFUL #define OS_64BIT_MAX 0xFFFFFFFFFFFFFFFFULL #define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF @@ -59,7 +57,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_SCHED_MAX_RESPONSE_TIME (UINT64)(OS_64BIT_MAX - 1U) typedef struct { LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM]; @@ -120,6 +117,7 @@ UINT32 OsShellShowTickRespo(VOID) { UINT32 intSave; UINT16 cpu; + UINT64 allTime; UINT32 tickSize = sizeof(SchedTickDebug) * LOSCFG_KERNEL_CORE_NUM; SchedTickDebug *schedDebug = (SchedTickDebug *)LOS_MemAlloc(m_aucSysMem1, tickSize); @@ -141,15 +139,18 @@ UINT32 OsShellShowTickRespo(VOID) PRINTK("cpu : %u sched data num : %u set time count : %u SortMax : %u\n", cpu, schedData->index, schedData->setTickCount, sortLinkNum[cpu]); UINT32 *data = schedData->tickResporeTime; - for (UINT32 i = 0; i < schedData->index; i++) { + allTime = 0; + for (UINT32 i = 1; i < schedData->index; i++) { + allTime += data[i]; UINT32 timeUs = (data[i] * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; PRINTK(" %u(%u)", timeUs, timeUs / OS_US_PER_TICK); - if ((i != 0) && ((i % 5) == 0)) { + if ((i != 0) && ((i % 5) == 0)) { /* A row of 5 data */ PRINTK("\n"); } } - PRINTK("\n"); + allTime = (allTime * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US; + PRINTK("\nTick Indicates the average response period: %llu(us)\n", allTime / (schedData->index - 1)); } (VOID)LOS_MemFree(m_aucSysMem1, schedDebug); @@ -279,6 +280,47 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) #endif } +STATIC INLINE VOID OsSchedTickReload(Percpu *currCpu, UINT64 nextResponseTime, UINT32 responseID, BOOL isTimeSlice) +{ + UINT64 currTime, nextExpireTime; + UINT32 usedTime; + + 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; + } + + nextExpireTime = currTime + nextResponseTime; + if (nextExpireTime >= currCpu->responseTime) { + return; + } + + 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 +} + STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) { @@ -287,6 +329,7 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, UINT64 nextResponseTime; BOOL isTimeSlice = FALSE; + currCpu->schedFlag &= ~INT_PEND_TICK; if (currCpu->responseID == oldResponseID) { /* This time has expired, and the next time the theory has expired is infinite */ currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; @@ -295,58 +338,44 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, /* The current thread's time slice has been consumed, but the current system lock task cannot * trigger the schedule to release the CPU */ - if (taskEndTime < nextExpireTime) { + if ((nextExpireTime > taskEndTime) && ((nextExpireTime - taskEndTime) > OS_SCHED_MINI_PERIOD)) { nextExpireTime = taskEndTime; isTimeSlice = TRUE; } - if ((currCpu->responseTime > nextExpireTime) && ((currCpu->responseTime - nextExpireTime) >= OS_CYCLE_PER_TICK)) { + if ((currCpu->responseTime > nextExpireTime) && + ((currCpu->responseTime - nextExpireTime) >= OS_TICK_RESPONSE_PRECISION)) { nextResponseTime = nextExpireTime - startTime; - if (nextResponseTime < OS_CYCLE_PER_TICK) { - nextResponseTime = OS_CYCLE_PER_TICK; - nextExpireTime = startTime + nextResponseTime; - if (nextExpireTime >= currCpu->responseTime) { - return; - } - } else if (nextResponseTime > g_schedTickMaxResponseTime) { + if (nextResponseTime > g_schedTickMaxResponseTime) { nextResponseTime = g_schedTickMaxResponseTime; - nextExpireTime = startTime + nextResponseTime; } } else { /* There is no point earlier than the current expiration date */ + currCpu->tickStartTime = 0; return; } - 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 + OsSchedTickReload(currCpu, nextResponseTime, responseID, isTimeSlice); } VOID OsSchedUpdateExpireTime(UINT64 startTime) { UINT64 endTime; + Percpu *cpu = OsPercpuGet(); LosTaskCB *runTask = OsCurrTaskGet(); + if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) { + cpu->schedFlag |= INT_PEND_TICK; + return; + } + if (runTask->policy == LOS_SCHED_RR) { LOS_SpinLock(&g_taskSpin); INT32 timeSlice = (runTask->timeSlice <= OS_TIME_SLICE_MIN) ? runTask->initTimeSlice : runTask->timeSlice; LOS_SpinUnlock(&g_taskSpin); endTime = startTime + timeSlice; } else { - endTime = OS_SCHED_MAX_RESPONSE_TIME; + endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; } OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, runTask->taskID); @@ -737,20 +766,23 @@ 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(); } needSched = sched->taskScan(); - currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; if (needSched) { LOS_MpSchedule(OS_MP_CPU_ALL); - currCpu->schedFlag = INT_PEND_RESCH; + currCpu->schedFlag |= INT_PEND_RESCH; } } + currCpu->schedFlag |= INT_PEND_TICK; + currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; } VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask) @@ -996,7 +1028,7 @@ STATIC VOID OsSchedTaskSwicth(LosTaskCB *runTask, LosTaskCB *newTask) if (newTask->policy == LOS_SCHED_RR) { endTime = newTask->startTime + newTask->timeSlice; } else { - endTime = OS_SCHED_MAX_RESPONSE_TIME; + endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; } OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, endTime, runTask->taskID); @@ -1017,11 +1049,11 @@ VOID OsSchedIrqEndCheckNeedSched(VOID) OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); if (runTask->timeSlice <= OS_TIME_SLICE_MIN) { - percpu->schedFlag = INT_PEND_RESCH; + percpu->schedFlag |= INT_PEND_RESCH; } - if (OsPreemptable() && (percpu->schedFlag == INT_PEND_RESCH)) { - percpu->schedFlag = INT_NO_RESCH; + if (OsPreemptable() && (percpu->schedFlag & INT_PEND_RESCH)) { + percpu->schedFlag &= ~INT_PEND_RESCH; LOS_SpinLock(&g_taskSpin); @@ -1037,7 +1069,9 @@ VOID OsSchedIrqEndCheckNeedSched(VOID) LOS_SpinUnlock(&g_taskSpin); } - OsSchedUpdateExpireTime(runTask->startTime); + if (percpu->schedFlag & INT_PEND_TICK) { + OsSchedUpdateExpireTime(runTask->startTime); + } } VOID OsSchedResched(VOID) @@ -1049,7 +1083,7 @@ VOID OsSchedResched(VOID) LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0); #endif - OsPercpuGet()->schedFlag = INT_NO_RESCH; + OsPercpuGet()->schedFlag &= ~INT_PEND_RESCH; LosTaskCB *runTask = OsCurrTaskGet(); LosTaskCB *newTask = OsGetTopTask(); if (runTask == newTask) { @@ -1065,7 +1099,7 @@ VOID LOS_Schedule(VOID) LosTaskCB *runTask = OsCurrTaskGet(); if (OS_INT_ACTIVE) { - OsPercpuGet()->schedFlag = INT_PEND_RESCH; + OsPercpuGet()->schedFlag |= INT_PEND_RESCH; return; } diff --git a/kernel/base/core/los_sortlink.c b/kernel/base/sched/sched_sq/los_sortlink.c similarity index 91% rename from kernel/base/core/los_sortlink.c rename to kernel/base/sched/sched_sq/los_sortlink.c index 1ca9fecd..91158926 100644 --- a/kernel/base/core/los_sortlink.c +++ b/kernel/base/sched/sched_sq/los_sortlink.c @@ -36,7 +36,6 @@ #include "los_sched_pri.h" #include "los_mp.h" - UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) { LOS_ListInit(&sortLinkHeader->sortLink); @@ -87,39 +86,19 @@ VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortL STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime) { - UINT64 expirTime = 0; - UINT64 nextExpirTime = 0; LOS_DL_LIST *head = &sortHeader->sortLink; LOS_DL_LIST *list = head->pstNext; if (LOS_ListEmpty(head)) { - return (UINT64)-1; - } - - do { - SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); - if (listSorted->responseTime <= startTime) { - expirTime = startTime; - list = list->pstNext; - } else { - nextExpirTime = listSorted->responseTime; - break; - } - } while (list != head); - - if (expirTime == 0) { - return nextExpirTime; - } - - if (nextExpirTime == 0) { - return expirTime; + return OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; } - if ((nextExpirTime - expirTime) <= OS_US_PER_TICK) { - return nextExpirTime; + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); + if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) { + return startTime + OS_TICK_RESPONSE_PRECISION; } - return expirTime; + return listSorted->responseTime; } STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID) diff --git a/kernel/include/los_swtmr.h b/kernel/include/los_swtmr.h index 1e595269..b12731b9 100644 --- a/kernel/include/los_swtmr.h +++ b/kernel/include/los_swtmr.h @@ -276,6 +276,7 @@ typedef struct tagSwTmrCtrl { that handles software timer timeout is called */ SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */ UINT32 uwOwnerPid; /** Owner of this software timer */ + UINT64 startTime; /**< Software timer start time */ } SWTMR_CTRL_S; /** diff --git a/platform/los_config.h b/platform/los_config.h index 36c3c4d5..b3c89951 100644 --- a/platform/los_config.h +++ b/platform/los_config.h @@ -97,6 +97,22 @@ extern UINT32 __heap_end; #define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick */ #endif +/** + * @ingroup los_config + * Minimum response error accuracy of tick interrupts, number of ticks in one second + */ +#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI +#define LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI 1000UL /* 1ms */ +#endif + +#if (LOSCFG_BASE_CORE_TICK_PER_SECOND > LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI) + #error "LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI must be greater than LOSCFG_BASE_CORE_TICK_PER_SECOND" +#endif + +#if (LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI > 1000UL) + #error "LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI must be less than or equal to 1000" +#endif + /** * @ingroup los_config * Microseconds of adjtime in one second -- GitLab