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

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


The following commit(s) were added to refs/heads/master by this push:
     new d8b4d534442 sched/tickless: Fix CLOCK_MONOTONIC always 0 by updating 
sched ticks
d8b4d534442 is described below

commit d8b4d53444222fae921af502b4a2af000a8dcac9
Author: chao an <[email protected]>
AuthorDate: Tue Mar 3 17:47:40 2026 +0800

    sched/tickless: Fix CLOCK_MONOTONIC always 0 by updating sched ticks
    
    Fix the issue where clock_gettime(CLOCK_MONOTONIC) always returns 0 in
    tickless mode, caused by the scheduler tick counter (g_system_ticks) not
    being updated with the actual timer ticks.
    
    1. Add clock_update_sched_ticks() function to 
sched/clock/clock_sched_ticks.c:
      a. This function directly sets the system tick counter to a specific value
         (vs incrementing in clock_increase_sched_ticks), with full 
documentation
         matching the existing code style.
      b. Uses seqlock to ensure thread-safe access to g_system_ticks.
    
    2. Call clock_update_sched_ticks() in nxsched_process_timer() 
(sched_processtickless.c):
    
      a. Syncs the scheduler tick counter with the actual timer ticks retrieved 
via up_timer_gettick().
    
    With this fix, g_system_ticks is properly updated in tickless mode,
    and clock_gettime(CLOCK_MONOTONIC) returns the correct non-zero monotonic 
time.
    
    Signed-off-by: chao an <[email protected]>
---
 sched/clock/clock.h                 | 73 +++++++++++++++++++++++++++++++++++++
 sched/clock/clock_sched_ticks.c     | 28 ++++++++++++++
 sched/sched/sched_processtickless.c | 10 ++++-
 3 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/sched/clock/clock.h b/sched/clock/clock.h
index a59ce4a8627..71b80297b09 100644
--- a/sched/clock/clock.h
+++ b/sched/clock/clock.h
@@ -70,15 +70,88 @@ extern spinlock_t g_basetime_lock;
  * Public Function Prototypes
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: clock_basetime
+ *
+ * Description:
+ *   Get the initial time value from the best source available.
+ *
+ ****************************************************************************/
+
 int  clock_basetime(FAR struct timespec *tp);
 
+/****************************************************************************
+ * Name: clock_initialize
+ *
+ * Description:
+ *   Perform one-time initialization of the timing facilities.
+ *
+ ****************************************************************************/
+
 void clock_initialize(void);
 
+/****************************************************************************
+ * Name: clock_update_sched_ticks
+ *
+ * Description:
+ *   Update the scheduler tick counter to a specific value. This function
+ *   directly sets the system tick counter to the given value (rather than
+ *   incrementing it), typically used for synchronizing or resetting the
+ *   scheduler tick count to a known state.
+ *
+ * Input Parameters:
+ *   ticks - The new value to set for the scheduler tick counter
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void clock_update_sched_ticks(clock_t ticks);
+
+/****************************************************************************
+ * Name: clock_increase_sched_ticks
+ *
+ * Description:
+ *   Increment the scheduler tick counter. This function should be called
+ *   each time the real-time clock interrupt occurs, indicating the passage
+ *   of one or more scheduling ticks.
+ *
+ * Input Parameters:
+ *   ticks - The number of ticks to increment (typically 1)
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
 void clock_increase_sched_ticks(clock_t ticks);
 
+/****************************************************************************
+ * Name: clock_get_sched_ticks
+ *
+ * Description:
+ *   Return the current value of the scheduler tick counter. This counter
+ *   only increases while the scheduler is running, and is independent of
+ *   the real-time clock.
+ *
+ * Returned Value:
+ *   The current number of scheduler ticks.
+ *
+ ****************************************************************************/
+
 clock_t clock_get_sched_ticks(void);
 
 #ifdef CONFIG_SCHED_CPULOAD_SYSCLK
+
+/****************************************************************************
+ * Name: cpuload_init
+ *
+ * Description:
+ *   Initialize the CPU load measurement logic.
+ *
+ ****************************************************************************/
+
 void cpuload_init(void);
 #endif
 
diff --git a/sched/clock/clock_sched_ticks.c b/sched/clock/clock_sched_ticks.c
index 353e4f3e0b1..282a51450f7 100644
--- a/sched/clock/clock_sched_ticks.c
+++ b/sched/clock/clock_sched_ticks.c
@@ -46,6 +46,34 @@ static seqcount_t g_system_tick_lock = SEQLOCK_INITIALIZER;
  * Public Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: clock_update_sched_ticks
+ *
+ * Description:
+ *   Update the scheduler tick counter to a specific value. This function
+ *   directly sets the system tick counter to the given value (rather than
+ *   incrementing it), typically used for synchronizing or resetting the
+ *   scheduler tick count to a known state.
+ *
+ * Input Parameters:
+ *   ticks - The new value to set for the scheduler tick counter
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void clock_update_sched_ticks(clock_t ticks)
+{
+  irqstate_t flags;
+
+  /* Increment the per-tick scheduler counter */
+
+  flags = write_seqlock_irqsave(&g_system_tick_lock);
+  g_system_ticks = ticks;
+  write_sequnlock_irqrestore(&g_system_tick_lock, flags);
+}
+
 /****************************************************************************
  * Name: clock_increase_sched_ticks
  *
diff --git a/sched/sched/sched_processtickless.c 
b/sched/sched/sched_processtickless.c
index 352d9f105ba..8eea08ad9bd 100644
--- a/sched/sched/sched_processtickless.c
+++ b/sched/sched/sched_processtickless.c
@@ -375,13 +375,17 @@ void nxsched_process_timer(void)
 {
 #ifdef CONFIG_HRTIMER
   uint64_t nsec = clock_systime_nsec();
+  clock_t ticks = NSEC2TICK(nsec);
+
+  clock_update_sched_ticks(ticks);
+
   hrtimer_process(nsec);
 
 #  if CONFIG_RR_INTERVAL > 0
   /* Workaround for SCHED_RR, see the note. */
 
   irqstate_t flags = enter_critical_section();
-  nxsched_process_event(div_const(nsec, (uint32_t)NSEC_PER_TICK), true);
+  nxsched_process_event(ticks, true);
   leave_critical_section(flags);
 #  endif
 
@@ -397,6 +401,10 @@ void nxsched_process_timer(void)
 
   up_timer_gettick(&ticks);
 
+  /* Update sched ticks */
+
+  clock_update_sched_ticks(ticks);
+
 #if CONFIG_RR_INTERVAL > 0
   /* Workaround for SCHED_RR, see the note. */
 

Reply via email to