This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch releases/13.0
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit fb4ffa4ae7c13452e43f15f19cd0d49be22c725b
Author: yushuailong <[email protected]>
AuthorDate: Wed Jun 10 19:21:07 2026 +0800

    drivers/timers: Fix non-atomic clock read in up_timer_gettime.
    
    up_timer_gettime() computed tv_sec and tv_nsec from two separate calls
    to current_usec(), which returns a free-running microsecond counter.
    The counter advances between the two calls, so a read that straddles a
    second boundary yields an inconsistent (possibly backwards) timespec.
    
    Read current_usec() once into a local variable and derive both fields
    from that single snapshot.
    
    Signed-off-by: yushuailong <[email protected]>
---
 drivers/timers/arch_timer.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/timers/arch_timer.c b/drivers/timers/arch_timer.c
index 5ee0da8c1de..5e3b0f988cd 100644
--- a/drivers/timers/arch_timer.c
+++ b/drivers/timers/arch_timer.c
@@ -309,11 +309,14 @@ int weak_function up_timer_gettick(FAR clock_t *ticks)
 int weak_function up_timer_gettime(struct timespec *ts)
 {
   int ret = -EAGAIN;
+  uint64_t usec;
 
   if (g_timer.lower != NULL)
     {
-      ts->tv_sec  = current_usec() / USEC_PER_SEC;
-      ts->tv_nsec = (current_usec() % USEC_PER_SEC) * NSEC_PER_USEC;
+      usec = current_usec();
+
+      ts->tv_sec  = usec / USEC_PER_SEC;
+      ts->tv_nsec = (usec % USEC_PER_SEC) * NSEC_PER_USEC;
       ret = OK;
     }
 

Reply via email to