fix: tick 动态化计算优化,消除中断执行时间对系统总体时间的影响,保证软件定时器的响应精度。
方案描述: 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 <zhushengle@huawei.com> Change-Id: Icd1159a1890046b13602b7a18dcd6234d5c61a89
This commit is contained in:
parent
9ec208a273
commit
8df3e8c965
|
@ -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" ]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,41 +280,27 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime)
|
|||
#endif
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
|
||||
UINT64 taskEndTime, UINT32 oldResponseID)
|
||||
STATIC INLINE VOID OsSchedTickReload(Percpu *currCpu, UINT64 nextResponseTime, UINT32 responseID, BOOL isTimeSlice)
|
||||
{
|
||||
UINT64 nextExpireTime = OsGetNextExpireTime(startTime);
|
||||
Percpu *currCpu = OsPercpuGet();
|
||||
UINT64 nextResponseTime;
|
||||
BOOL isTimeSlice = FALSE;
|
||||
UINT64 currTime, nextExpireTime;
|
||||
UINT32 usedTime;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
nextExpireTime = taskEndTime;
|
||||
isTimeSlice = TRUE;
|
||||
}
|
||||
|
||||
if ((currCpu->responseTime > nextExpireTime) && ((currCpu->responseTime - nextExpireTime) >= OS_CYCLE_PER_TICK)) {
|
||||
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) {
|
||||
nextResponseTime = g_schedTickMaxResponseTime;
|
||||
nextExpireTime = startTime + nextResponseTime;
|
||||
}
|
||||
currTime = OsGetCurrSchedTimeCycle();
|
||||
if (currCpu->tickStartTime != 0) {
|
||||
usedTime = currTime - currCpu->tickStartTime;
|
||||
currCpu->tickStartTime = 0;
|
||||
} else {
|
||||
/* There is no point earlier than the current expiration date */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -323,7 +310,6 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
|
|||
} else {
|
||||
currCpu->responseID = OS_INVALID_VALUE;
|
||||
}
|
||||
|
||||
currCpu->responseTime = nextExpireTime;
|
||||
HalClockTickTimerReload(nextResponseTime);
|
||||
|
||||
|
@ -335,18 +321,61 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
|
|||
#endif
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
|
||||
UINT64 taskEndTime, UINT32 oldResponseID)
|
||||
{
|
||||
UINT64 nextExpireTime = OsGetNextExpireTime(startTime);
|
||||
Percpu *currCpu = OsPercpuGet();
|
||||
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;
|
||||
}
|
||||
|
||||
/* The current thread's time slice has been consumed, but the current system lock task cannot
|
||||
* trigger the schedule to release the CPU
|
||||
*/
|
||||
if ((nextExpireTime > taskEndTime) && ((nextExpireTime - taskEndTime) > OS_SCHED_MINI_PERIOD)) {
|
||||
nextExpireTime = taskEndTime;
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode);
|
||||
if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) {
|
||||
return startTime + OS_TICK_RESPONSE_PRECISION;
|
||||
}
|
||||
|
||||
if (nextExpirTime == 0) {
|
||||
return expirTime;
|
||||
}
|
||||
|
||||
if ((nextExpirTime - expirTime) <= OS_US_PER_TICK) {
|
||||
return nextExpirTime;
|
||||
}
|
||||
|
||||
return expirTime;
|
||||
return listSorted->responseTime;
|
||||
}
|
||||
|
||||
STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID)
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue