mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
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:
parent
1d08a9d019
commit
1a3185beeb
1 changed files with 6 additions and 4 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue