MCPcopy Create free account
hub / github.com/aws/clock-bound / feed

Method feed

clock-bound/src/daemon/clock_sync_algorithm/ff/ntp.rs:69–189  ·  view source on GitHub ↗

Feed an event into this algorithm Returns [`Some`] if the event has improved this source's [`ClockParameters`].

(&mut self, event: event::Ntp)

Source from the content-addressed store, hash-verified

67 ///
68 /// Returns [`Some`] if the event has improved this source's [`ClockParameters`].
69 pub fn feed(&mut self, event: event::Ntp) -> Option<&ClockParameters> {
70 // FIXME: take a MONOTONIC_COARSE timestamp *before* computing the clock error bound.
71 //
72 // The only use of this timestamp is to support and maintain the behavior for clients built
73 // against ClockBound 2.0. These clients grow the CEB by calculating the time elapsed
74 // between the instant the ClockParameters were computed, and the instant they read the
75 // system clock. This needs to be a bit pessimistic, and the `as_of_monotonic` timestamp
76 // should be taken *before* the time at which the CEB is calculated.
77 //
78 // Here this should be *before* the TSC post read of event fed to the algorithm. That would
79 // require carrying this `as_of_monotonic` timestamp from the IO components. Instead, we
80 // are taking a short cut and placing this timestamp slightly in the past, by 10
81 // milliseconds to account for possible events where the daemon is scheduled out.
82 //
83 // The CEB is made worse by around 150 nanoseconds (assuming a 15PPM oscillator drift),
84 // which is negligible for ClockBound 2.0 clients. Moving this timestamp in the past may
85 // also help reduce the risk of causality breach errors seen when using the
86 // CLOCK_MONOTONIC_COARSE clock.
87 //
88 // This will be eliminated once we decide to stop supporting ClockBound 2.0 clients.
89 let as_of_monotonic = MonotonicCoarse.get_time();
90 let as_of_monotonic = if as_of_monotonic > Instant::from_millis(10) {
91 as_of_monotonic - Duration::from_millis(10)
92 } else {
93 Instant::from_millis(0)
94 };
95
96 let tsc_midpoint = event.tsc_midpoint();
97
98 // First update the internal local (current SKM) and estimate (long term)
99 // sample buffers
100 let within_threshold = self
101 .feed_internal_buffers(event)
102 .inspect_err(|error_msg| match error_msg {
103 FeedError::Old { event, .. } => {
104 tracing::warn!(?event, ?error_msg);
105 }
106 })
107 .ok()?; // early exit if there was an error with the sample
108
109 if !within_threshold {
110 // At this point, if the input does not meet our expectations on the rtt threshold,
111 // there is no more processing to do. The end calculation will not be more accurate than
112 // the previous value (if we have one)
113 tracing::trace!("Early exit. Event not within threshold");
114 return None;
115 }
116
117 // Functionality from this point will fill out the equation
118 // `C(t) = TSC(t) × p^ + K − θ^(t)` where:
119 // - `C(t)` is the absolute time. Corrected. This is effectively the output of the clock sync algorithm
120 // - `TSC(t)` is the tsc reading at a time
121 // - `p^` is the estimation of the clock period
122 // - `K` is the "epoch" (the uncorrected time at `TSC(0)`)
123 // - `θ^(t)` is the time correction
124
125 // Calculate uncorrected clock, aka `p^` and `K`
126 self.uncorrected_clock = Self::calculate_uncorrected_clock(&self.local, &self.estimate);

Calls 6

tsc_midpointMethod · 0.80
time_atMethod · 0.80
more_accurate_thanMethod · 0.80
get_timeMethod · 0.45
feed_internal_buffersMethod · 0.45
as_refMethod · 0.45