Skip to content

Take the server clock from CLOCK_MONOTONIC_RAW on Linux - #99

Merged
kahrendt merged 2 commits into
mainfrom
clock-monotonic-raw
Oct 17, 2026
Merged

kahrendt merged 2 commits into
mainfrom
clock-monotonic-raw

Conversation

@kahrendt

@kahrendt kahrendt commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

On Linux, now_us() read CLOCK_MONOTONIC, whose rate NTP slews (by
up to 500 ppm). Every timestamp the server sends follows that rate, so
the clients' time filters had to track each change the NTP daemon made.
The server clock now runs at the hardware's own rate.

Change

  • now_us() reads CLOCK_MONOTONIC_RAW on Linux. ESP-IDF keeps its
    esp_timer CLOCK_MONOTONIC, and macOS keeps mach_continuous_time,
    neither of which NTP slews.
  • Docs: clock.h and SendspinServer::now_us() drop the claim that
    the clock counts through system sleep on Linux, which neither clock
    did.
  • The host's Timer re-arms a wait that ends before now_us() reaches
    its deadline. Asio waits on the slewed CLOCK_MONOTONIC, which can run
    ahead of the raw clock, and a caller that rechecks and returns would
    never run again: the drain check would leave on_drained pending, and
    SessionDriver skips re-arming an unchanged deadline. ESP-IDF's loop
    already fires only once now_us() reaches the deadline.

Tests

  • Clock.ReadsTheMonotonicClockInMicroseconds reads
    CLOCK_MONOTONIC_RAW as its reference on both hosts.
  • No test for the early wake: a test cannot make the steady clock run
    ahead of the raw one. The Linux path was compiled with -Werror and run in a
    container, where now_us() matched CLOCK_MONOTONIC_RAW.
  • Gap: on x86_64 kernels older than 5.3, CLOCK_MONOTONIC_RAW is a
    syscall rather than a vDSO read.

NTP slews CLOCK_MONOTONIC's rate, which the clients' time filters then
have to follow. The raw clock runs at the hardware's own rate. The docs
of now_us() no longer claim it counts through sleep on Linux, which
neither clock does.
@kahrendt
kahrendt marked this pull request as ready for review October 17, 2026 10:37
Copilot AI balanced review requested due to automatic review settings October 17, 2026 10:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The Linux clock test needs an updated reference, and early timer expiry can leave drain completion pending indefinitely.

2 open issues
What changed in this PR

This PR switches the server’s Linux timestamp clock to CLOCK_MONOTONIC_RAW so NTP adjustments no longer change its rate.

Changes:

  • Switch Linux clock reads while preserving macOS and ESP-IDF behavior.
  • Correct clock documentation and clarify steady-clock timer drift.
File Description
src/​transport.h Clarifies timer clock drift.
src/​clock.h Documents platform clocks and NTP independence.
src/​clock.cpp Selects CLOCK_MONOTONIC_RAW on Linux.
include/​sendspin/​server/​server.h Updates the public clock description.

Review effort: Balanced

Comment thread src/clock.cpp
Comment thread src/clock.cpp
On Linux the steady clock Asio waits on is NTP-slewed CLOCK_MONOTONIC,
which can run ahead of now_us()'s raw clock, so a wait could end short
of at_us. A caller that rechecks and returns, as the drain check does,
then never ran again. The clock test reads CLOCK_MONOTONIC_RAW, as
now_us() does on both hosts.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Static review found no blocking issues in clock selection or timer lifecycle handling; tests were not run.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

@kahrendt
kahrendt merged commit 62c3a2d into main Oct 17, 2026
14 checks passed
@kahrendt
kahrendt deleted the clock-monotonic-raw branch October 17, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants