mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +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
|
#endif
|
||||||
static clock_t nxsched_process_scheduler(clock_t ticks, clock_t elapsed,
|
static clock_t nxsched_process_scheduler(clock_t ticks, clock_t elapsed,
|
||||||
bool noswitches);
|
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
|
* Private Data
|
||||||
@@ -111,25 +111,34 @@ int up_timer_gettick(FAR clock_t *ticks)
|
|||||||
}
|
}
|
||||||
#endif
|
#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 next;
|
||||||
clock_t elapsed;
|
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;
|
/* Process the timer ticks and set up the next interval (or not) */
|
||||||
g_timer_tick = ticks;
|
|
||||||
|
|
||||||
/* 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);
|
static void nxsched_wdog_expiration(wdparm_t arg)
|
||||||
nxsched_timer_start(ticks, next);
|
{
|
||||||
|
/* 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)
|
if (interval != CLOCK_MAX)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(interval <= UINT32_MAX);
|
DEBUGASSERT(interval <= UINT32_MAX);
|
||||||
wd_start_abstick(&g_sched_event, ticks + interval,
|
wd_start_abstick(&g_sched_event, ticks + interval,
|
||||||
nxsched_process_event, 0u);
|
nxsched_wdog_expiration, 0u);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wd_cancel(&g_sched_event);
|
wd_cancel(&g_sched_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return interval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -349,6 +356,18 @@ void nxsched_process_tick(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
up_timer_gettick(&ticks);
|
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);
|
wd_timer(ticks);
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
@@ -393,7 +412,14 @@ void nxsched_process_tick(void)
|
|||||||
|
|
||||||
void nxsched_reassess_timer(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