mirror of
https://github.com/apache/nuttx.git
synced 2026-05-23 14:58:13 +08:00
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:
committed by
Donny(董九柱)
parent
6901864210
commit
4280e69a1c
@@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
Reference in New Issue
Block a user