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 601c43603b

View file

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