sched_processtimer: use atomic to protect g_timer_interval and g_timer_tick

reason:
We would like to replace the critical section with a small lock.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2024-12-11 12:24:11 +08:00
parent aa0aecbd80
commit dfcc6adcf6

View file

@ -106,6 +106,24 @@ static unsigned int g_timer_interval;
* Private Functions
****************************************************************************/
static inline_function void set_g_time_tick(clock_t tick)
{
#ifdef CONFIG_SYSTEM_TIME64
atomic64_set((FAR atomic64_t *)&g_timer_tick, tick);
#else
atomic_set((FAR atomic_t *)&g_timer_tick, tick);
#endif
}
static inline_function clock_t get_g_time_tick()
{
#ifdef CONFIG_SYSTEM_TIME64
return atomic64_read((FAR atomic64_t *)&g_timer_tick);
#else
return atomic_read((FAR atomic_t *)&g_timer_tick);
#endif
}
#if !defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT) && !defined(CONFIG_CLOCK_TIMEKEEPING)
int up_timer_gettick(FAR clock_t *ticks)
{
@ -377,6 +395,7 @@ static clock_t nxsched_timer_process(clock_t ticks, clock_t elapsed,
static clock_t nxsched_timer_start(clock_t ticks, clock_t interval)
{
irqstate_t flags;
int ret;
if (interval > 0)
@ -388,6 +407,8 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval)
}
#endif
flags = enter_critical_section();
#ifdef CONFIG_SCHED_TICKLESS_ALARM
/* Convert the delay to a time in the future (with respect
* to the time when last stopped the timer).
@ -400,6 +421,8 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval)
ret = up_timer_tick_start(interval);
#endif
leave_critical_section(flags);
if (ret < 0)
{
serr("ERROR: up_timer_start/up_alarm_start failed: %d\n", ret);
@ -439,22 +462,18 @@ void nxsched_alarm_tick_expiration(clock_t ticks)
{
clock_t elapsed;
clock_t nexttime;
irqstate_t flags;
/* Save the time that the alarm occurred */
flags = enter_critical_section();
elapsed = ticks - g_timer_tick;
g_timer_tick = ticks;
leave_critical_section(flags);
elapsed = ticks - get_g_time_tick();
set_g_time_tick(ticks);
/* Process the timer ticks and set up the next interval (or not) */
nexttime = nxsched_timer_process(ticks, elapsed, false);
flags = enter_critical_section();
g_timer_interval = nxsched_timer_start(ticks, nexttime);
leave_critical_section(flags);
elapsed = nxsched_timer_start(ticks, nexttime);
atomic_set((FAR atomic_t *)&g_timer_interval, elapsed);
}
void nxsched_alarm_expiration(FAR const struct timespec *ts)
@ -490,23 +509,19 @@ void nxsched_timer_expiration(void)
clock_t ticks;
clock_t elapsed;
clock_t nexttime;
irqstate_t flags;
/* Get the interval associated with last expiration */
flags = enter_critical_section();
up_timer_gettick(&ticks);
g_timer_tick = ticks;
elapsed = g_timer_interval;
leave_critical_section(flags);
set_g_time_tick(ticks);
elapsed = atomic_read((FAR atomic_t *)&g_timer_interval);
/* Process the timer ticks and set up the next interval (or not) */
nexttime = nxsched_timer_process(ticks, elapsed, false);
flags = enter_critical_section();
g_timer_interval = nxsched_timer_start(ticks, nexttime);
leave_critical_section(flags);
elapsed = nxsched_timer_start(ticks, nexttime);
atomic_set((FAR atomic_t *)&g_timer_interval, elapsed);
}
#endif
@ -565,13 +580,15 @@ void nxsched_reassess_timer(void)
/* Convert this to the elapsed time and update clock tickbase */
elapsed = ticks - g_timer_tick;
g_timer_tick = ticks;
elapsed = ticks - get_g_time_tick();
set_g_time_tick(ticks);
/* Process the timer ticks and start next timer */
nexttime = nxsched_timer_process(ticks, elapsed, true);
g_timer_interval = nxsched_timer_start(ticks, nexttime);
elapsed = nxsched_timer_start(ticks, nexttime);
atomic_set((FAR atomic_t *)&g_timer_interval, elapsed);
}
/****************************************************************************
@ -590,12 +607,10 @@ void nxsched_reassess_timer(void)
clock_t nxsched_get_next_expired(void)
{
irqstate_t flags;
sclock_t ret;
flags = enter_critical_section();
ret = g_timer_tick + g_timer_interval - clock_systime_ticks();
leave_critical_section(flags);
ret = get_g_time_tick() + atomic_read((FAR atomic_t *)&g_timer_interval) -
clock_systime_ticks();
return ret < 0 ? 0 : ret;
}