Skip to content

fix(time_slave): use free-running clock for gPTP timestamps - #285

Open
gordon9901 wants to merge 1 commit into
eclipse-score:mainfrom
gordon9901:fix_gptp_free_running_timestamp
Open

gordon9901 wants to merge 1 commit into
eclipse-score:mainfrom
gordon9901:fix_gptp_free_running_timestamp

Conversation

@gordon9901

Copy link
Copy Markdown
Contributor

Summary

gPTP timestamps must come from a free-running local clock that is never adjusted by the time synchronization itself (feat_req_time_veh_free_run_ts). Previously, two problems violated this:

  1. QNX (qnx_raw_shim.cpp) cascaded per-message through BPF hardware timestamp → PTP_GET_TIME (PHC read) → clock_gettime(CLOCK_REALTIME). CLOCK_REALTIME is the System Clock that score::time keeps aligned to Absolute Time, so it can step between two timestamps and falsify the peer-delay and rate-ratio calculations.
  2. Linux (raw_socket.cpp) returned an all-zero hwts with a success code when no hardware timestamp was present, so a missing timestamp was silently treated as a valid timestamp of 0 by GptpEngine::HandlePacket and PeerDelayMeasurer.

Changes

  • Lock the timestamp source once per interface (Linux: EnableHwTimestamping(); QNX: BIOCSTSTAMP result at qnx_raw_open()), and never mix sources within one interface's lifetime, so all timestamps of one Sync/Follow_Up evaluation or one peer-delay measurement come from the same clock.
  • Software fallback is now CLOCK_MONOTONIC on both platforms — never CLOCK_REALTIME, and never the Linux kernel's SOF_TIMESTAMPING_*_SOFTWARE (which is itself CLOCK_REALTIME-based).
  • Missing timestamps are no longer treated as 0. Recv()/Send() return the sentinel kNoHwTimestamp ({-1, 0}), and GptpEngine::HandlePacket discards the affected message (Sync / Pdelay_Req / Pdelay_Resp) instead of using a fabricated value. SendPDelayResponseAndFollowUp skips sending the Follow_Up when t3 is missing.
  • Unit tests cover source selection and missing-timestamp handling on both Linux and QNX (the QNX decision logic is extracted into a pure, host-buildable SelectTimestamp() function so it is unit-testable without a full syscall-DI layer).
  • Detailed design (docs/detailed_design/index.rst) now documents the timestamp sources and the missing-timestamp discard behavior, and removes the inaccurate "fallback does not affect protocol correctness" claim.

Acceptance criteria

  • TimeSlave selects the timestamp source once per network interface: hardware timestamps if supported, otherwise software timestamps from a free-running monotonic clock.
  • No gPTP timestamp is taken from CLOCK_REALTIME, on QNX and on Linux.
  • All timestamps of one Sync/Follow_Up evaluation and of one peer-delay measurement come from the same clock.
  • A missing timestamp is not used as 0; the affected message or measurement is discarded.
  • Unit tests cover source selection and missing-timestamp handling on QNX and on Linux.
  • The detailed design describes the timestamp sources.

Closes #257

@github-actions

Copy link
Copy Markdown
Contributor

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.6.0) and connecting to it...
INFO: Invocation ID: 3eb0b3fc-c10b-4982-b298-932db038e603
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
WARNING: For repository 'platforms', the root module requires module version platforms@1.0.0, but got platforms@1.1.0 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
WARNING: For repository 'rules_oci', the root module requires module version rules_oci@2.2.7, but got rules_oci@2.3.0 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
WARNING: /home/runner/.bazel/external/score_baselibs+/score/json/BUILD:24:12: target '@@score_baselibs+//score/json:base_library' is deprecated: base_library no longer has any effect, vaJson is the only parser backend. Remove this flag from your build configuration; it will be deleted in a future release.
Loading: 
Loading: 3 packages loaded
WARNING: Target pattern parsing failed.
ERROR: Skipping '//:license-check': no such target '//:license-check': target 'license-check' not declared in package '' defined by /home/runner/work/time/time/BUILD
ERROR: no such target '//:license-check': target 'license-check' not declared in package '' defined by /home/runner/work/time/time/BUILD
INFO: Elapsed time: 15.784s
INFO: 0 processes.
ERROR: Build did NOT complete successfully
ERROR: Build failed. Not running target

@gordon9901 gordon9901 self-assigned this Oct 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Quality pack traceability report for this pull request:

Status: PASS (workflow run)

Traceability gate input: /home/runner/work/time/time/_build/metrics.json
------------------------------------------------------------------------
[comp_req]
  Requirements with source links: 9/58 (15.52%)
  Requirements with test links:   5/58 (8.62%)
  Requirements fully linked:      5/58 (8.62%)
  Tests linked to requirements:   8/450 (1.78%)
  Broken test references:         0
------------------------------------------------------------------------
Threshold check passed.

@github-actions

Copy link
Copy Markdown
Contributor

Documentation preview for this pull request is available at:
pr-285: https://eclipse-score.github.io/time/pr-285/

This branch is waiting to be deployed

1 waiting deployment
workflow-approval — f227f113 Waiting Oct 29, 2026 by gordon9901 via qnx-build (arm64-qnx) / approval #1122
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

score/time_slave: Take gPTP timestamps from a free-running clock only

1 participant