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. */