mirror of
https://github.com/apache/nuttx.git
synced 2026-08-18 01:49:24 +08:00
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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user