Skip to content

sched/clock: fix stale CLOCK_MONOTONIC on SCHED_TICKLESS - #19905

Merged
xiaoxiang781216 merged 1 commit into
apache:masterfrom
raiden00pl:clock_monotonic_fix
Aug 20, 2026
Merged

sched/clock: fix stale CLOCK_MONOTONIC on SCHED_TICKLESS#19905
xiaoxiang781216 merged 1 commit into
apache:masterfrom
raiden00pl:clock_monotonic_fix

Conversation

@raiden00pl

@raiden00pl raiden00pl commented Aug 20, 2026

Copy link
Copy Markdown
Member

Summary

clock_gettime(CLOCK_MONOTONIC) reads g_system_ticks, which is only refreshed when a timer expiration is processed. On SCHED_TICKLESS an idle system has no timeout armed, so the clock returns 0 before the first expiration and a frozen value afterwards.

This regressed in commit c7b6442, which switched CLOCK_MONOTONIC to the sched tick counter to exclude suspended time. Excluding suspend time needs explicit accounting maintained by PM code, the tick counter cannot provide it on tickless.

Restore the live read. On non-tickless builds clock_systime_timespec() falls back to the same tick counter, so behavior there is unchanged.

Impact

fix issue from #17199 (comment)

Testing

verified on qemu-intel64, nrf52840-dk and rv-virt.

CPython 3.13 REPL on qemu-intel64:python (SCHED_TICKLESS, TSC deadline timer), system idle at the prompt between reads:

  1. without this fix:
>>> import time
>>> time.monotonic()                          # ~5 s after boot
0.0
>>> time.monotonic()                          # ~5 s later
0.0
>>> time.clock_gettime(time.CLOCK_BOOTTIME)   # wall clock is fine
15.31824313
  1. with this fix:
>>> import time
>>> time.monotonic()                                                                                                                                                                                                                                                           
10.226251524                                                                                                                                                                                                                                                                   
>>> time.monotonic()                                                                                                                                                                                                                                                           
15.279083686                                                                                                                                                                                                                                                                   
>>> time.clock_gettime(time.CLOCK_BOOTTIME)                                                                                                                                                                                                                                    
15.332810769                                                                                                                                                                                                                                                                   

clock_gettime(CLOCK_MONOTONIC) reads g_system_ticks, which is only
refreshed when a timer expiration is processed. On SCHED_TICKLESS an
idle system has no timeout armed, so the clock returns 0 before the
first expiration and a frozen value afterwards.

This regressed in commit c7b6442, which switched CLOCK_MONOTONIC to
the sched tick counter to exclude suspended time. Excluding suspend time
needs explicit accounting maintained by PM code, the tick counter cannot
provide it on tickless.

Restore the live read.  On non-tickless builds clock_systime_timespec()
falls back to the same tick counter, so behavior there is unchanged.

Verified on qemu-intel64, nrf52840-dk and rv-virt.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
@raiden00pl

Copy link
Copy Markdown
Member Author

FYI @anchao @wangchdo

@github-actions github-actions Bot added Area: OS Components OS Components issues Size: S The size of the change in this PR is small labels Aug 20, 2026
@github-actions

Copy link
Copy Markdown

MemBrowse Memory Report

arduino-mega2560

  • flash: .text -186 B (-0.3%, 67,356 B / 262,144 B, total: 26% used)

esp32-devkitc

  • ROM: .flash.text -28 B (-0.0%, 124,380 B / 4,194,272 B, total: 3% used)
  • irom0_0_seg: .flash.text -28 B (-0.0%, 88,584 B / 3,342,304 B, total: 3% used)

hifive1-revb

  • flash: .text -80 B (-0.1%, 83,300 B / 4,194,304 B, total: 2% used)

qemu-armv8a

  • Code: .text.nxclock_gettime -48 B (-0.0%, 318,952 B)

qemu-intel64

  • Code: .text -83 B (-0.0%, 8,658,979 B)

rx65n-rsk2mb

  • ROM: .text -32 B (-0.0%, 87,296 B / 2,097,152 B, total: 4% used)

s698pm-dkit

@acassis

acassis commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Let's mark @wangchdo it could be important to his internal usage as well.
@anchao for visibility

@xiaoxiang781216
xiaoxiang781216 merged commit 612f9a0 into apache:master Aug 20, 2026
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: OS Components OS Components issues Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants