arch/risc-v/esp32c3-legacy: Fix non-atomic clock read in up_rtc_rdalarm.

up_rtc_rdalarm() computed tv_sec and tv_nsec from two separate
evaluations of rt_timer_time_us() + offset + deadline. The RT timer
advances between the two calls, so a read that straddles a second
boundary yields an inconsistent timespec.

Compute the microsecond value once into a local variable and derive
both fields from that single snapshot.

Signed-off-by: yushuailong <yyyusl@qq.com>
This commit is contained in:
yushuailong 2026-06-10 19:21:30 +08:00 committed by Xiang Xiao
parent 1d08a9d019
commit 1a3185beeb

View file

@ -3383,6 +3383,7 @@ int up_rtc_rdalarm(struct timespec *tp, uint32_t alarmid)
{
irqstate_t flags;
struct alm_cbinfo_s *cbinfo;
uint64_t time_us;
DEBUGASSERT(tp != NULL);
DEBUGASSERT((RTC_ALARM0 <= alarmid) &&
(alarmid < RTC_ALARM_LAST));
@ -3393,10 +3394,11 @@ int up_rtc_rdalarm(struct timespec *tp, uint32_t alarmid)
cbinfo = &g_alarmcb[alarmid];
tp->tv_sec = (rt_timer_time_us() + g_rtc_save->offset +
cbinfo->deadline_us) / USEC_PER_SEC;
tp->tv_nsec = ((rt_timer_time_us() + g_rtc_save->offset +
cbinfo->deadline_us) % USEC_PER_SEC) * NSEC_PER_USEC;
time_us = rt_timer_time_us() + g_rtc_save->offset +
cbinfo->deadline_us;
tp->tv_sec = time_us / USEC_PER_SEC;
tp->tv_nsec = (time_us % USEC_PER_SEC) * NSEC_PER_USEC;
spin_unlock_irqrestore(&g_rtc_lock, flags);