arch/xtensa/espressif: Fix non-atomic clock read in esp_rtc_rdalarm.

esp_rtc_rdalarm() computed tv_sec and tv_nsec from two separate
evaluations of esp_hr_timer_time_us() + offset + deadline. The
high-resolution 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-17 17:12:04 +08:00
committed by Xiang Xiao
parent fb4ffa4ae7
commit fb2f117ec2
+6 -4
View File
@@ -611,6 +611,7 @@ static int esp_rtc_rdalarm(struct rtc_lowerhalf_s *lower,
struct timespec ts;
struct alm_cbinfo_s *cbinfo;
irqstate_t flags;
uint64_t time_us;
DEBUGASSERT(lower != NULL);
DEBUGASSERT(alarminfo != NULL);
@@ -624,10 +625,11 @@ static int esp_rtc_rdalarm(struct rtc_lowerhalf_s *lower,
cbinfo = &priv->alarmcb[alarminfo->id];
ts.tv_sec = (esp_hr_timer_time_us() + g_rtc_save->offset +
cbinfo->deadline_us) / USEC_PER_SEC;
ts.tv_nsec = ((esp_hr_timer_time_us() + g_rtc_save->offset +
cbinfo->deadline_us) % USEC_PER_SEC) * NSEC_PER_USEC;
time_us = esp_hr_timer_time_us() + g_rtc_save->offset +
cbinfo->deadline_us;
ts.tv_sec = time_us / USEC_PER_SEC;
ts.tv_nsec = (time_us % USEC_PER_SEC) * NSEC_PER_USEC;
localtime_r(&ts.tv_sec, (struct tm *)alarminfo->time);