sched/sched: Avoid getting tick in the nxsched_process_event.

During the expiration, the g_wdexpired has already updated, so only nxsched_reassess_timer requires getting current tick again.
This commit avoided getting tick again in the nxsched_process_event.

Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
ouyangxiangzhen
2026-01-12 20:07:10 +08:00
committed by Donny(董九柱)
parent 6901864210
commit 4280e69a1c
+42 -16
View File
@@ -78,7 +78,7 @@ static clock_t nxsched_cpu_scheduler(int cpu, clock_t ticks,
#endif
static clock_t nxsched_process_scheduler(clock_t ticks, clock_t elapsed,
bool noswitches);
static clock_t nxsched_timer_start(clock_t ticks, clock_t interval);
static void nxsched_timer_start(clock_t ticks, clock_t interval);
/****************************************************************************
* Private Data
@@ -111,25 +111,34 @@ int up_timer_gettick(FAR clock_t *ticks)
}
#endif
static void nxsched_process_event(wdparm_t noswitches)
static void nxsched_process_event(clock_t ticks, bool noswitches)
{
clock_t ticks;
clock_t next;
clock_t elapsed;
/* Get the current time. */
/* Ensure the g_timer_tick is monotonic. */
up_timer_gettick(&ticks);
if (clock_compare(g_timer_tick, ticks))
{
/* Calculate the elapsed time and update clock tickbase. */
/* Calculate the elapsed time and update clock tickbase. */
elapsed = ticks - g_timer_tick;
g_timer_tick = ticks;
elapsed = ticks - g_timer_tick;
g_timer_tick = ticks;
/* Process the timer ticks and set up the next interval (or not) */
/* Process the timer ticks and set up the next interval (or not) */
next = nxsched_process_scheduler(ticks, elapsed, noswitches);
nxsched_timer_start(ticks, next);
}
}
next = nxsched_process_scheduler(ticks, elapsed, (bool)noswitches);
nxsched_timer_start(ticks, next);
static void nxsched_wdog_expiration(wdparm_t arg)
{
/* Since the g_wdexpired has updated in the nxsched_timer_expiration,
* here we do not need to get tick again.
*/
nxsched_process_event(g_wdexpired, false);
}
/****************************************************************************
@@ -301,20 +310,18 @@ clock_t nxsched_process_scheduler(clock_t ticks, clock_t elapsed,
*
****************************************************************************/
static clock_t nxsched_timer_start(clock_t ticks, clock_t interval)
static void nxsched_timer_start(clock_t ticks, clock_t interval)
{
if (interval != CLOCK_MAX)
{
DEBUGASSERT(interval <= UINT32_MAX);
wd_start_abstick(&g_sched_event, ticks + interval,
nxsched_process_event, 0u);
nxsched_wdog_expiration, 0u);
}
else
{
wd_cancel(&g_sched_event);
}
return interval;
}
/****************************************************************************
@@ -349,6 +356,18 @@ void nxsched_process_tick(void)
*/
up_timer_gettick(&ticks);
#if CONFIG_RR_INTERVAL > 0
/* The current SCHED_RR implementation has an issue: if a round-robin task
* is preempted, its timeslice counter does not decrement properly.
* Therefore, we must trigger the scheduler on each timer expiration to
* minimize the occurrence of this problem.
* This workaround can be removed once the SCHED_RR behavior is fixed.
*/
nxsched_process_event(ticks, true);
#endif
wd_timer(ticks);
leave_critical_section(flags);
@@ -393,7 +412,14 @@ void nxsched_process_tick(void)
void nxsched_reassess_timer(void)
{
nxsched_process_event(1u);
/* If we are in the wdog callback, there is no need to get tick again. */
if (!wd_in_callback())
{
up_timer_gettick(&g_wdexpired);
}
nxsched_process_event(g_wdexpired, true);
}
/****************************************************************************