| 477 | fbclock_truetime* truetime, |
| 478 | int time_standard) { |
| 479 | int64_t phc_time_ns = state->phc_time_ns; |
| 480 | if (state->ingress_time_ns > phc_time_ns) { |
| 481 | return FBCLOCK_E_PHC_IN_THE_PAST; |
| 482 | } |
| 483 | int64_t diff_ns = sysclock_time_now_ns - state->sysclock_time_ns; |
| 484 | // Refuse to extrapolate past a sane bound, or backwards in time. Either case |
| 485 | // means the daemon stopped updating shared memory or there's a clock-source |
| 486 | // mismatch, so the extrapolated PHC time would have unbounded error. |
| 487 | if (diff_ns < 0 || diff_ns > FBCLOCK_MAX_EXTRAPOLATION_NS) { |
| 488 | return FBCLOCK_E_DATA_STALE; |
| 489 | } |
| 490 | // NANOSECONDS_IN_SECONDS is uint64_t, which would otherwise convert the |
| 491 | // signed dividend to unsigned. When coef_ppb is negative the product is |
| 492 | // negative, and that conversion turns it into a value near 2^64, making |
| 493 | // the quotient ~2^64/1e9 ≈ 18.45 s instead of the intended small ns count. |
| 494 | phc_time_ns += |
| 495 | diff_ns + diff_ns * state->coef_ppb / (int64_t)NANOSECONDS_IN_SECONDS; |
| 496 | |
| 497 | // Time since the last SYNC from the GM, at the PHC instant this call |
| 498 | // reports. Clamped like the past_v2 path below: a coef_ppb under -1e9 |
| 499 | // extrapolates back past ingress, and fbclock_window_of_uncertainty casts |
| 500 | // the holdover product to uint64_t. |
| 501 | int64_t holdover_ns = phc_time_ns - state->ingress_time_ns; |
| 502 | double seconds = |
| 503 | holdover_ns > 0 ? (double)holdover_ns / NANOSECONDS_IN_SECONDS : 0.0; |
| 504 | |
| 505 | // UTC offset applied if time standard used is UTC (and not TAI) |
| 506 | if (time_standard == FBCLOCK_UTC) { |
| 507 | phc_time_ns = fbclock_apply_utc_offset_v2(state, phc_time_ns); |
| 508 | } |
| 509 | |
| 510 | // calculate the Window of Uncertainty (WOU) (in nanoseconds) |
| 511 | uint64_t wou_ns = |
| 512 | fbclock_window_of_uncertainty(seconds, error_bound_ns, h_value_ns); |
| 513 | truetime->earliest_ns = phc_time_ns - wou_ns; |
| 514 | truetime->latest_ns = phc_time_ns + wou_ns; |
| 515 | return FBCLOCK_E_NO_ERROR; |
| 516 | } |
no test coverage detected
searching dependent graphs…