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

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

commit 51bc4d756d28947233d1ad74a1e083bc66731476
Author: ouyangxiangzhen <[email protected]>
AuthorDate: Wed Aug 26 10:49:49 2026 +0800

    sched/hrtimer: Skip redundant hardware reprogram via cached target
    
    Cache the programmed expiration in a global g_hrtimer_expected and
    skip reprogramming the hardware timer when the target is unchanged,
    reducing interrupt overhead. g_oneshot_maxticks clamp gains uint64_t
    cast to avoid overflow.
    
    Assisted-By: mimo-v2.6-pro
    Signed-off-by: ouyangxiangzhen <[email protected]>
---
 sched/hrtimer/hrtimer.h            | 66 ++++++++++++++++++++++----------------
 sched/hrtimer/hrtimer_initialize.c |  4 +++
 sched/hrtimer/hrtimer_start.c      |  2 +-
 3 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/sched/hrtimer/hrtimer.h b/sched/hrtimer/hrtimer.h
index 7f4a2aa168d..18b1bb65505 100644
--- a/sched/hrtimer/hrtimer.h
+++ b/sched/hrtimer/hrtimer.h
@@ -104,6 +104,10 @@ extern struct FAR hrtimer_s *g_hrtimer_head;
 extern struct list_node g_hrtimer_list;
 #endif
 
+#ifdef CONFIG_SCHED_TICKLESS
+extern uint64_t g_hrtimer_expected;
+#endif
+
 #ifdef CONFIG_SMP
 /* Array of pointers to currently running high-resolution timers
  * for each CPU in SMP configurations. Index corresponds to CPU ID.
@@ -219,42 +223,46 @@ static inline_function void hrtimer_reprogram(uint64_t 
next_expired)
   uint64_t        delay;
   uint64_t        expired = hrtimer_last_expired();
 
-#if CONFIG_HRTIMER_PRECISION_SHIFT > 0
-  /* Ceiling-align the target expiration time to the precision boundary.
-   * This coarsens the timer resolution to (1 << SHIFT) nanoseconds,
-   * reducing the frequency of hardware timer reprogramming.
-   */
+  if (g_hrtimer_expected != next_expired)
+    {
+      g_hrtimer_expected = next_expired;
+#  if CONFIG_HRTIMER_PRECISION_SHIFT > 0
+      /* Ceiling-align the target expiration time to the precision boundary.
+       * This coarsens the timer resolution to (1 << SHIFT) nanoseconds,
+       * reducing the frequency of hardware timer reprogramming.
+       */
 
-  next_expired = (next_expired + HRTIMER_PRECISION_MASK) &
-                 ~HRTIMER_PRECISION_MASK;
-#endif
+      next_expired = (next_expired + HRTIMER_PRECISION_MASK) &
+                     ~HRTIMER_PRECISION_MASK;
+#  endif
 
-  delay = HRTIMER_TIME_BEFORE_EQ(expired, next_expired) ?
-          next_expired - expired : 0u;
+      delay = HRTIMER_TIME_BEFORE_EQ(expired, next_expired) ?
+              next_expired - expired : 0u;
 
 #  ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
-  delay = delay < TICK2NSEC((uint64_t)g_oneshot_maxticks) ?
-          delay : TICK2NSEC((uint64_t)g_oneshot_maxticks);
+      delay = delay < TICK2NSEC((uint64_t)g_oneshot_maxticks) ?
+              delay : TICK2NSEC((uint64_t)g_oneshot_maxticks);
 #  endif
 
-  /* Even if overflow occurs here, the functional correctness
-   * should still be fine.
-   */
+      /* Even if overflow occurs here, the functional correctness
+       * should still be fine.
+       */
 
-  delay -= CONFIG_TIMER_ADJUST_NSEC;
+      delay -= CONFIG_TIMER_ADJUST_NSEC;
 
-  clock_nsec2time(&ts, expired + delay);
+      clock_nsec2time(&ts, expired + delay);
 
 #  ifdef CONFIG_SCHED_TICKLESS_ALARM
-  ret = up_alarm_start(&ts);
+      ret = up_alarm_start(&ts);
 #  else
-  struct timespec current;
-  up_timer_gettime(&current);
-  clock_timespec_subtract(&ts, &current, &ts);
-  ret = up_timer_start(&ts);
+      struct timespec current;
+      up_timer_gettime(&current);
+      clock_timespec_subtract(&ts, &current, &ts);
+      ret = up_timer_start(&ts);
 #  endif
 
-  DEBUGASSERT(ret == 0);
+      DEBUGASSERT(ret == 0);
+    }
 #endif
 }
 
@@ -600,9 +608,9 @@ int hrtimer_cancel_running(FAR hrtimer_t *timer)
  *
  ****************************************************************************/
 
-#ifdef CONFIG_SMP
 static inline_function void hrtimer_wait(FAR hrtimer_t *timer)
 {
+#ifdef CONFIG_SMP
   int cpu;
 
   DEBUGASSERT(timer && timer->func == NULL);
@@ -634,10 +642,8 @@ static inline_function void hrtimer_wait(FAR hrtimer_t 
*timer)
     }
 
   /* Finally, we acquire the ownership of this hrtimer. */
-}
-#else
-#  define hrtimer_wait(timer) /* Nothing to wait in non-SMP. */
 #endif
+}
 
 /****************************************************************************
  * Name: hrtimer_process
@@ -667,6 +673,12 @@ static inline_function void hrtimer_process(uint64_t now)
   int                 cpu = this_cpu();
   irqstate_t        flags = hrtimer_lock();
 
+#ifdef CONFIG_SCHED_TICKLESS
+  /* Invalidate the g_hrtimer_expected */
+
+  g_hrtimer_expected = now;
+#endif
+
   /* Acquire the lock and seize the ownership of the hrtimer queue. */
 
   for (; ; )
diff --git a/sched/hrtimer/hrtimer_initialize.c 
b/sched/hrtimer/hrtimer_initialize.c
index 0b8beaf53cb..eac9ec26a8b 100644
--- a/sched/hrtimer/hrtimer_initialize.c
+++ b/sched/hrtimer/hrtimer_initialize.c
@@ -32,6 +32,10 @@
  * Public Data
  ****************************************************************************/
 
+#ifdef CONFIG_SCHED_TICKLESS
+uint64_t g_hrtimer_expected;
+#endif
+
 #ifdef CONFIG_SMP
 /* Array of pointers to currently running high-resolution timers
  * for each CPU in SMP configurations. Index corresponds to CPU ID.
diff --git a/sched/hrtimer/hrtimer_start.c b/sched/hrtimer/hrtimer_start.c
index 4ec4e0ca6c7..719cb3a0e54 100644
--- a/sched/hrtimer/hrtimer_start.c
+++ b/sched/hrtimer/hrtimer_start.c
@@ -84,7 +84,7 @@ int hrtimer_start_absolute(FAR hrtimer_t *hrtimer, 
hrtimer_entry_t func,
 
   reprogram |= hrtimer_insert(hrtimer);
 
-  /* If the inserted timer is now the earliest, start hardware timer */
+  /* If the inserted timer is now the earliest, start hardware timer. */
 
   if (reprogram)
     {

Reply via email to