提交 e64ee0f4 编写于 作者: O openharmony_ci 提交者: Gitee

!518 fix: tick 动态化计算优化,消除中断执行时间对系统总体时间的影响,保证软件定时器的响应精度。

Merge pull request !518 from zhushengle/sched_tick
...@@ -34,7 +34,6 @@ kernel_module(module_name) { ...@@ -34,7 +34,6 @@ kernel_module(module_name) {
sources = [ sources = [
"core/los_bitmap.c", "core/los_bitmap.c",
"core/los_process.c", "core/los_process.c",
"core/los_sortlink.c",
"core/los_swtmr.c", "core/los_swtmr.c",
"core/los_sys.c", "core/los_sys.c",
"core/los_task.c", "core/los_task.c",
...@@ -68,6 +67,7 @@ kernel_module(module_name) { ...@@ -68,6 +67,7 @@ kernel_module(module_name) {
"mp/los_stat.c", "mp/los_stat.c",
"om/los_err.c", "om/los_err.c",
"sched/sched_sq/los_sched.c", "sched/sched_sq/los_sched.c",
"sched/sched_sq/los_sortlink.c",
"vm/los_vm_boot.c", "vm/los_vm_boot.c",
"vm/los_vm_dump.c", "vm/los_vm_dump.c",
"vm/los_vm_fault.c", "vm/los_vm_fault.c",
...@@ -83,9 +83,7 @@ kernel_module(module_name) { ...@@ -83,9 +83,7 @@ kernel_module(module_name) {
] ]
if (defined(LOSCFG_SHELL_CMD_DEBUG)) { if (defined(LOSCFG_SHELL_CMD_DEBUG)) {
configs += [ configs += [ "$HDFTOPDIR:hdf_config" ]
"$HDFTOPDIR:hdf_config"
]
} }
public_configs = [ ":public" ] public_configs = [ ":public" ]
......
...@@ -178,10 +178,9 @@ ERROR: ...@@ -178,10 +178,9 @@ ERROR:
* Description: Start Software Timer * Description: Start Software Timer
* Input : swtmr --- Need to 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; UINT32 ticks;
UINT64 currTime = OsGetCurrSchedTimeCycle();
if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
(swtmr->ucMode == LOS_SWTMR_MODE_OPP) || (swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
...@@ -192,10 +191,8 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) ...@@ -192,10 +191,8 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr)
} }
swtmr->ucState = OS_SWTMR_STATUS_TICKING; swtmr->ucState = OS_SWTMR_STATUS_TICKING;
OsAdd2SortLink(&swtmr->stSortList, currTime, ticks, OS_SORT_LINK_SWTMR); OsAdd2SortLink(&swtmr->stSortList, swtmr->startTime, ticks, OS_SORT_LINK_SWTMR);
if (OS_SCHEDULER_ACTIVE) { OsSchedUpdateExpireTime(currTime);
OsSchedUpdateExpireTime(currTime);
}
return; return;
} }
...@@ -211,7 +208,7 @@ STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) ...@@ -211,7 +208,7 @@ STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr)
swtmr->uwOwnerPid = 0; 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); LOS_SpinLock(&g_swtmrSpin);
SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool);
...@@ -236,7 +233,7 @@ STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, SWTMR_CTRL_S *swtmr) ...@@ -236,7 +233,7 @@ STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, SWTMR_CTRL_S *swtmr)
swtmr->ucState = OS_SWTMR_STATUS_CREATED; swtmr->ucState = OS_SWTMR_STATUS_CREATED;
} else { } else {
swtmr->uwOverrun++; swtmr->uwOverrun++;
OsSwtmrStart(swtmr); OsSwtmrStart(currTime, swtmr);
} }
LOS_SpinUnlock(&g_swtmrSpin); LOS_SpinUnlock(&g_swtmrSpin);
...@@ -267,12 +264,12 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) ...@@ -267,12 +264,12 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)
UINT64 currTime = OsGetCurrSchedTimeCycle(); UINT64 currTime = OsGetCurrSchedTimeCycle();
while (sortList->responseTime <= currTime) { while (sortList->responseTime <= currTime) {
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); 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_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); LOS_SpinUnlock(&cpu->swtmrSortLinkSpin);
OsWakePendTimeSwtmr(cpu, swtmr); OsWakePendTimeSwtmr(cpu, currTime, swtmr);
LOS_SpinLock(&cpu->swtmrSortLinkSpin); LOS_SpinLock(&cpu->swtmrSortLinkSpin);
if (LOS_ListEmpty(listObject)) { if (LOS_ListEmpty(listObject)) {
...@@ -305,9 +302,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) ...@@ -305,9 +302,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr)
swtmr->ucState = OS_SWTMR_STATUS_CREATED; swtmr->ucState = OS_SWTMR_STATUS_CREATED;
swtmr->uwOverrun = 0; swtmr->uwOverrun = 0;
if (OS_SCHEDULER_ACTIVE) { OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle());
OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle());
}
} }
/* /*
...@@ -403,7 +398,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) ...@@ -403,7 +398,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
OsSwtmrStop(swtmr); OsSwtmrStop(swtmr);
/* fall-through */ /* fall-through */
case OS_SWTMR_STATUS_CREATED: case OS_SWTMR_STATUS_CREATED:
OsSwtmrStart(swtmr); swtmr->startTime = OsGetCurrSchedTimeCycle();
OsSwtmrStart(swtmr->startTime, swtmr);
break; break;
default: default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID; ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
......
...@@ -57,6 +57,7 @@ typedef struct { ...@@ -57,6 +57,7 @@ typedef struct {
SortLinkAttribute swtmrSortLink; /* swtmr sort link */ SortLinkAttribute swtmrSortLink; /* swtmr sort link */
SPIN_LOCK_S swtmrSortLinkSpin; /* swtmr sort link spin lock */ SPIN_LOCK_S swtmrSortLinkSpin; /* swtmr sort link spin lock */
UINT64 responseTime; /* Response time for current nuclear Tick interrupts */ 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 */ UINT32 responseID; /* The response ID of the current nuclear TICK interrupt */
UINTPTR runProcess; /* The address of the process control block pointer to which UINTPTR runProcess; /* The address of the process control block pointer to which
the current kernel is running */ the current kernel is running */
......
...@@ -45,6 +45,10 @@ extern "C" { ...@@ -45,6 +45,10 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#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; extern UINT32 g_taskScheduled;
typedef BOOL (*SchedScan)(VOID); typedef BOOL (*SchedScan)(VOID);
...@@ -86,8 +90,9 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID) ...@@ -86,8 +90,9 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID)
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) #define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
typedef enum { typedef enum {
INT_NO_RESCH = 0, /* no needs to schedule */ INT_NO_RESCH = 0x0, /* no needs to schedule */
INT_PEND_RESCH, /* pending schedule flag */ INT_PEND_RESCH = 0x1, /* pending schedule flag */
INT_PEND_TICK = 0x2, /* pending tick */
} SchedFlag; } SchedFlag;
/* Check if preemptable with counter flag */ /* Check if preemptable with counter flag */
...@@ -102,7 +107,7 @@ STATIC INLINE BOOL OsPreemptable(VOID) ...@@ -102,7 +107,7 @@ STATIC INLINE BOOL OsPreemptable(VOID)
BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0); BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0);
if (!preemptable) { if (!preemptable) {
/* Set schedule flag if preemption is disabled */ /* Set schedule flag if preemption is disabled */
OsPercpuGet()->schedFlag = INT_PEND_RESCH; OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
} }
LOS_IntRestore(intSave); LOS_IntRestore(intSave);
return preemptable; return preemptable;
...@@ -124,7 +129,7 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID) ...@@ -124,7 +129,7 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID)
#endif #endif
if (!preemptable) { if (!preemptable) {
/* Set schedule flag if preemption is disabled */ /* Set schedule flag if preemption is disabled */
OsPercpuGet()->schedFlag = INT_PEND_RESCH; OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
} }
return preemptable; return preemptable;
...@@ -139,8 +144,8 @@ STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave) ...@@ -139,8 +144,8 @@ STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave)
{ {
if (cpu->taskLockCnt > 0) { if (cpu->taskLockCnt > 0) {
cpu->taskLockCnt--; cpu->taskLockCnt--;
if ((cpu->taskLockCnt == 0) && (cpu->schedFlag == INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { if ((cpu->taskLockCnt == 0) && (cpu->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) {
cpu->schedFlag = INT_NO_RESCH; cpu->schedFlag &= ~INT_PEND_RESCH;
LOS_IntRestore(intSave); LOS_IntRestore(intSave);
LOS_Schedule(); LOS_Schedule();
return; return;
......
...@@ -62,6 +62,7 @@ typedef struct { ...@@ -62,6 +62,7 @@ typedef struct {
#define OS_SORT_LINK_INVALID_TIME ((UINT64)-1) #define OS_SORT_LINK_INVALID_TIME ((UINT64)-1)
#define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->responseTime = (value)) #define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->responseTime = (value))
#define GET_SORTLIST_VALUE(sortList) (((SortLinkList *)(sortList))->responseTime)
extern UINT64 OsGetNextExpireTime(UINT64 startTime); extern UINT64 OsGetNextExpireTime(UINT64 startTime);
extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader); extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader);
......
...@@ -54,6 +54,9 @@ LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrStatus[][SWTMR_STRLEN] = { ...@@ -54,6 +54,9 @@ LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrStatus[][SWTMR_STRLEN] = {
STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr) STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr)
{ {
UINT32 ticks = 0;
(VOID)LOS_SwtmrTimeGet(swtmr->usTimerID, &ticks);
PRINTK("0x%08x " PRINTK("0x%08x "
"%-7s " "%-7s "
"%-6s " "%-6s "
...@@ -65,7 +68,7 @@ STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr) ...@@ -65,7 +68,7 @@ STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr)
g_shellSwtmrStatus[swtmr->ucState], g_shellSwtmrStatus[swtmr->ucState],
g_shellSwtmrMode[swtmr->ucMode], g_shellSwtmrMode[swtmr->ucMode],
swtmr->uwInterval, swtmr->uwInterval,
swtmr->uwCount, ticks,
swtmr->uwArg, swtmr->uwArg,
swtmr->pfnHandler); swtmr->pfnHandler);
} }
......
...@@ -56,7 +56,7 @@ VOID OsMpScheduleHandler(VOID) ...@@ -56,7 +56,7 @@ VOID OsMpScheduleHandler(VOID)
* set schedule flag to differ from wake function, * set schedule flag to differ from wake function,
* so that the scheduler can be triggered at the end of irq. * 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) VOID OsMpHaltHandler(VOID)
......
...@@ -47,8 +47,6 @@ ...@@ -47,8 +47,6 @@
#include "los_stat_pri.h" #include "los_stat_pri.h"
#endif #endif
#define OS_32BIT_MAX 0xFFFFFFFFUL #define OS_32BIT_MAX 0xFFFFFFFFUL
#define OS_64BIT_MAX 0xFFFFFFFFFFFFFFFFULL #define OS_64BIT_MAX 0xFFFFFFFFFFFFFFFFULL
#define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF #define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF
...@@ -59,7 +57,6 @@ ...@@ -59,7 +57,6 @@
#define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN) #define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN)
#define OS_SCHED_READY_MAX 30 #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_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 { typedef struct {
LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM]; LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM];
...@@ -120,6 +117,7 @@ UINT32 OsShellShowTickRespo(VOID) ...@@ -120,6 +117,7 @@ UINT32 OsShellShowTickRespo(VOID)
{ {
UINT32 intSave; UINT32 intSave;
UINT16 cpu; UINT16 cpu;
UINT64 allTime;
UINT32 tickSize = sizeof(SchedTickDebug) * LOSCFG_KERNEL_CORE_NUM; UINT32 tickSize = sizeof(SchedTickDebug) * LOSCFG_KERNEL_CORE_NUM;
SchedTickDebug *schedDebug = (SchedTickDebug *)LOS_MemAlloc(m_aucSysMem1, tickSize); SchedTickDebug *schedDebug = (SchedTickDebug *)LOS_MemAlloc(m_aucSysMem1, tickSize);
...@@ -141,15 +139,18 @@ UINT32 OsShellShowTickRespo(VOID) ...@@ -141,15 +139,18 @@ UINT32 OsShellShowTickRespo(VOID)
PRINTK("cpu : %u sched data num : %u set time count : %u SortMax : %u\n", PRINTK("cpu : %u sched data num : %u set time count : %u SortMax : %u\n",
cpu, schedData->index, schedData->setTickCount, sortLinkNum[cpu]); cpu, schedData->index, schedData->setTickCount, sortLinkNum[cpu]);
UINT32 *data = schedData->tickResporeTime; 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; UINT32 timeUs = (data[i] * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US;
PRINTK(" %u(%u)", timeUs, timeUs / OS_US_PER_TICK); 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");
} }
} }
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); (VOID)LOS_MemFree(m_aucSysMem1, schedDebug);
...@@ -279,6 +280,47 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) ...@@ -279,6 +280,47 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime)
#endif #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, STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
UINT64 taskEndTime, UINT32 oldResponseID) UINT64 taskEndTime, UINT32 oldResponseID)
{ {
...@@ -287,6 +329,7 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, ...@@ -287,6 +329,7 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
UINT64 nextResponseTime; UINT64 nextResponseTime;
BOOL isTimeSlice = FALSE; BOOL isTimeSlice = FALSE;
currCpu->schedFlag &= ~INT_PEND_TICK;
if (currCpu->responseID == oldResponseID) { if (currCpu->responseID == oldResponseID) {
/* This time has expired, and the next time the theory has expired is infinite */ /* This time has expired, and the next time the theory has expired is infinite */
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
...@@ -295,58 +338,44 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, ...@@ -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 /* The current thread's time slice has been consumed, but the current system lock task cannot
* trigger the schedule to release the CPU * trigger the schedule to release the CPU
*/ */
if (taskEndTime < nextExpireTime) { if ((nextExpireTime > taskEndTime) && ((nextExpireTime - taskEndTime) > OS_SCHED_MINI_PERIOD)) {
nextExpireTime = taskEndTime; nextExpireTime = taskEndTime;
isTimeSlice = TRUE; 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; nextResponseTime = nextExpireTime - startTime;
if (nextResponseTime < OS_CYCLE_PER_TICK) { if (nextResponseTime > g_schedTickMaxResponseTime) {
nextResponseTime = OS_CYCLE_PER_TICK;
nextExpireTime = startTime + nextResponseTime;
if (nextExpireTime >= currCpu->responseTime) {
return;
}
} else if (nextResponseTime > g_schedTickMaxResponseTime) {
nextResponseTime = g_schedTickMaxResponseTime; nextResponseTime = g_schedTickMaxResponseTime;
nextExpireTime = startTime + nextResponseTime;
} }
} else { } else {
/* There is no point earlier than the current expiration date */ /* There is no point earlier than the current expiration date */
currCpu->tickStartTime = 0;
return; return;
} }
if (isTimeSlice) { OsSchedTickReload(currCpu, nextResponseTime, responseID, 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
} }
VOID OsSchedUpdateExpireTime(UINT64 startTime) VOID OsSchedUpdateExpireTime(UINT64 startTime)
{ {
UINT64 endTime; UINT64 endTime;
Percpu *cpu = OsPercpuGet();
LosTaskCB *runTask = OsCurrTaskGet(); LosTaskCB *runTask = OsCurrTaskGet();
if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) {
cpu->schedFlag |= INT_PEND_TICK;
return;
}
if (runTask->policy == LOS_SCHED_RR) { if (runTask->policy == LOS_SCHED_RR) {
LOS_SpinLock(&g_taskSpin); LOS_SpinLock(&g_taskSpin);
INT32 timeSlice = (runTask->timeSlice <= OS_TIME_SLICE_MIN) ? runTask->initTimeSlice : runTask->timeSlice; INT32 timeSlice = (runTask->timeSlice <= OS_TIME_SLICE_MIN) ? runTask->initTimeSlice : runTask->timeSlice;
LOS_SpinUnlock(&g_taskSpin); LOS_SpinUnlock(&g_taskSpin);
endTime = startTime + timeSlice; endTime = startTime + timeSlice;
} else { } else {
endTime = OS_SCHED_MAX_RESPONSE_TIME; endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION;
} }
OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, runTask->taskID); OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, runTask->taskID);
...@@ -737,20 +766,23 @@ VOID OsSchedTick(VOID) ...@@ -737,20 +766,23 @@ VOID OsSchedTick(VOID)
Sched *sched = g_sched; Sched *sched = g_sched;
Percpu *currCpu = OsPercpuGet(); Percpu *currCpu = OsPercpuGet();
BOOL needSched = FALSE; BOOL needSched = FALSE;
LosTaskCB *runTask = OsCurrTaskGet();
currCpu->tickStartTime = runTask->irqStartTime;
if (currCpu->responseID == OS_INVALID_VALUE) { if (currCpu->responseID == OS_INVALID_VALUE) {
if (sched->swtmrScan != NULL) { if (sched->swtmrScan != NULL) {
(VOID)sched->swtmrScan(); (VOID)sched->swtmrScan();
} }
needSched = sched->taskScan(); needSched = sched->taskScan();
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
if (needSched) { if (needSched) {
LOS_MpSchedule(OS_MP_CPU_ALL); 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) VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask)
...@@ -996,7 +1028,7 @@ STATIC VOID OsSchedTaskSwicth(LosTaskCB *runTask, LosTaskCB *newTask) ...@@ -996,7 +1028,7 @@ STATIC VOID OsSchedTaskSwicth(LosTaskCB *runTask, LosTaskCB *newTask)
if (newTask->policy == LOS_SCHED_RR) { if (newTask->policy == LOS_SCHED_RR) {
endTime = newTask->startTime + newTask->timeSlice; endTime = newTask->startTime + newTask->timeSlice;
} else { } 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); OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, endTime, runTask->taskID);
...@@ -1017,11 +1049,11 @@ VOID OsSchedIrqEndCheckNeedSched(VOID) ...@@ -1017,11 +1049,11 @@ VOID OsSchedIrqEndCheckNeedSched(VOID)
OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle());
if (runTask->timeSlice <= OS_TIME_SLICE_MIN) { if (runTask->timeSlice <= OS_TIME_SLICE_MIN) {
percpu->schedFlag = INT_PEND_RESCH; percpu->schedFlag |= INT_PEND_RESCH;
} }
if (OsPreemptable() && (percpu->schedFlag == INT_PEND_RESCH)) { if (OsPreemptable() && (percpu->schedFlag & INT_PEND_RESCH)) {
percpu->schedFlag = INT_NO_RESCH; percpu->schedFlag &= ~INT_PEND_RESCH;
LOS_SpinLock(&g_taskSpin); LOS_SpinLock(&g_taskSpin);
...@@ -1037,7 +1069,9 @@ VOID OsSchedIrqEndCheckNeedSched(VOID) ...@@ -1037,7 +1069,9 @@ VOID OsSchedIrqEndCheckNeedSched(VOID)
LOS_SpinUnlock(&g_taskSpin); LOS_SpinUnlock(&g_taskSpin);
} }
OsSchedUpdateExpireTime(runTask->startTime); if (percpu->schedFlag & INT_PEND_TICK) {
OsSchedUpdateExpireTime(runTask->startTime);
}
} }
VOID OsSchedResched(VOID) VOID OsSchedResched(VOID)
...@@ -1049,7 +1083,7 @@ VOID OsSchedResched(VOID) ...@@ -1049,7 +1083,7 @@ VOID OsSchedResched(VOID)
LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0); LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0);
#endif #endif
OsPercpuGet()->schedFlag = INT_NO_RESCH; OsPercpuGet()->schedFlag &= ~INT_PEND_RESCH;
LosTaskCB *runTask = OsCurrTaskGet(); LosTaskCB *runTask = OsCurrTaskGet();
LosTaskCB *newTask = OsGetTopTask(); LosTaskCB *newTask = OsGetTopTask();
if (runTask == newTask) { if (runTask == newTask) {
...@@ -1065,7 +1099,7 @@ VOID LOS_Schedule(VOID) ...@@ -1065,7 +1099,7 @@ VOID LOS_Schedule(VOID)
LosTaskCB *runTask = OsCurrTaskGet(); LosTaskCB *runTask = OsCurrTaskGet();
if (OS_INT_ACTIVE) { if (OS_INT_ACTIVE) {
OsPercpuGet()->schedFlag = INT_PEND_RESCH; OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
return; return;
} }
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include "los_sched_pri.h" #include "los_sched_pri.h"
#include "los_mp.h" #include "los_mp.h"
UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
{ {
LOS_ListInit(&sortLinkHeader->sortLink); LOS_ListInit(&sortLinkHeader->sortLink);
...@@ -87,39 +86,19 @@ VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortL ...@@ -87,39 +86,19 @@ VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortL
STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime) STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime)
{ {
UINT64 expirTime = 0;
UINT64 nextExpirTime = 0;
LOS_DL_LIST *head = &sortHeader->sortLink; LOS_DL_LIST *head = &sortHeader->sortLink;
LOS_DL_LIST *list = head->pstNext; LOS_DL_LIST *list = head->pstNext;
if (LOS_ListEmpty(head)) { if (LOS_ListEmpty(head)) {
return (UINT64)-1; return OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION;
}
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;
} }
if ((nextExpirTime - expirTime) <= OS_US_PER_TICK) { SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode);
return nextExpirTime; if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) {
return startTime + OS_TICK_RESPONSE_PRECISION;
} }
return expirTime; return listSorted->responseTime;
} }
STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID) STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID)
......
...@@ -276,6 +276,7 @@ typedef struct tagSwTmrCtrl { ...@@ -276,6 +276,7 @@ typedef struct tagSwTmrCtrl {
that handles software timer timeout is called */ that handles software timer timeout is called */
SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */ SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */
UINT32 uwOwnerPid; /** Owner of this software timer */ UINT32 uwOwnerPid; /** Owner of this software timer */
UINT64 startTime; /**< Software timer start time */
} SWTMR_CTRL_S; } SWTMR_CTRL_S;
/** /**
......
...@@ -97,6 +97,22 @@ extern UINT32 __heap_end; ...@@ -97,6 +97,22 @@ extern UINT32 __heap_end;
#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick */ #define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick */
#endif #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 * @ingroup los_config
* Microseconds of adjtime in one second * Microseconds of adjtime in one second
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册