1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Low-overhead timing without hiding the details from you.
//!
//! # Core abstractions
//!
//! - [`Time`]: Defines the `Instant` and `Duration` types for a clock domain and
//! the arithmetic between them.
//! - [`Clock`]: Provides [`Clock::now`] and names the associated [`Time`] and
//! [`DurationCalibration`] types.
//! - [`DurationCalibration`]: Converts durations to/from nanoseconds as `u64`.
//! - [`CalibratedClock`]: Bundles a [`Clock`] with its calibration for convenient passing.
//! - [`ClockSynchronization`]: Correlates instants between two clock domains.
//!
//! # Standard library clocks
//!
//! [`std_clocks::InstantClock`] and [`std_clocks::SystemClock`] wrap
//! `std::time::Instant` and `std::time::SystemTime`. They use [`InherentlyCalibrated`],
//! as their duration type is directly convertible to/from nanoseconds.
//!
//! # Hardware clocks
//!
//! [`tsc::Tsc`] reads the x86_64 timestamp counter. Its ticks are not nanoseconds,
//! so calibration via [`wrapping_u64::U64Calibration`] is required. Calibration also
//! produces a [`ClockSynchronization`] that can convert TSC instants to
//! `std::time::Instant` and vice versa.
//!
//! ```
//! # #[cfg(all(feature = "tsc", target_arch = "x86_64"))]
//! # {
//! # use fast_clock::{Clock, DurationCalibration, CalibratedClock, InherentlyCalibrated};
//! # use fast_clock::tsc::Tsc;
//! # use fast_clock::wrapping_u64::{U64Calibration, WrappingU64Time};
//! # use fast_clock::Time;
//!
//! let tsc = Tsc::try_new_assume_stable().unwrap();
//! let (calibration, sync) = U64Calibration::new_with_std_instant(
//! &tsc,
//! std::time::Duration::from_millis(100),
//! );
//! let clock = CalibratedClock { clock: tsc, calibration };
//!
//! let t0 = clock.clock.now();
//! // ... timed section ...
//! let t1 = clock.clock.now();
//!
//! let duration = WrappingU64Time::instant_sub(t1, t0);
//! let duration_ns: u64 = clock.calibration.convert_to_ns(duration);
//!
//! // Convert a TSC instant to std::time::Instant using the synchronization point.
//! let std_instant = sync.to_a(t0, &InherentlyCalibrated, &clock.calibration);
//! # }
//! ```
//!
//! # Features
//!
//! | Feature | Default | Description |
//! |---------|---------|-------------|
//! | `std` | yes | Enables [`std_clocks`] and `std`-dependent methods. |
//! | `tsc` | yes | Enables [`tsc`] (x86_64 only). |
//!
//! Contributions adding more clocks are welcome.
extern crate std;
use ;
pub use ClockSynchronization;
/// Arithmetic types and operations for a clock domain.
///
/// Most users will use the provided implementations: [`std_clocks::InstantTime`],
/// [`std_clocks::SystemTimeTime`], and [`wrapping_u64::WrappingU64Time`].
/// A source of time readings.
///
/// Call [`Clock::now`] to sample an instant.
/// Converts a clock's native duration type to and from nanoseconds.
/// A [`Clock`] bundled with its [`DurationCalibration`].
/// Calibration type for clocks whose native duration is already in nanoseconds.
///
/// Used with [`std_clocks::InstantClock`] and [`std_clocks::SystemClock`].
;