1#![expect(clippy::print_stdout, reason = "a tour prints what it finds")]
10
11use core::fmt::Display;
12use core::hint::black_box;
13use std::process::ExitCode;
14
15use t2t::Timedelta;
16#[cfg(target_os = "linux")]
17use t2t::clock::TaiClock;
18use t2t::clock::{
19 BootClock, Clock, CoarseMonotonicClock, CoarseSystemClock, Counter, MonotonicClock,
20 ProcessCpuClock, RawMonotonicClock, SystemClock, ThreadCpuClock,
21};
22
23const READINGS: i64 = 100_000;
25
26fn main() -> ExitCode {
27 let counter = match Counter::discover() {
28 Ok(counter) => counter,
29 Err(error) => {
30 #[expect(clippy::print_stderr, reason = "the person running the tour reads why")]
31 {
32 eprintln!("clock-tour: {error}");
33 }
34 return ExitCode::FAILURE;
35 },
36 };
37 println!("{:<21} {}\n", "Counter's rate", counter.rate());
38 report(&counter, "SystemClock", &SystemClock);
39 report(&counter, "CoarseSystemClock", &CoarseSystemClock);
40 #[cfg(target_os = "linux")]
41 report(&counter, "TaiClock", &TaiClock);
42 report(&counter, "MonotonicClock", &MonotonicClock);
43 report(&counter, "CoarseMonotonicClock", &CoarseMonotonicClock);
44 report(&counter, "RawMonotonicClock", &RawMonotonicClock);
45 report(&counter, "BootClock", &BootClock);
46 report(&counter, "ProcessCpuClock", &ProcessCpuClock);
47 report(&counter, "ThreadCpuClock", &ThreadCpuClock);
48 report(&counter, "Counter", &counter);
49 ExitCode::SUCCESS
50}
51
52fn report<C: Clock<Reading: Display>>(counter: &Counter, name: &str, clock: &C) {
54 println!("{name:<21} {:<36} {} a reading", clock.now(), cost(counter, clock));
55}
56
57fn cost<C: Clock>(counter: &Counter, clock: &C) -> Timedelta {
59 let start = counter.now();
60 for _ in 0..READINGS {
61 black_box(clock.now());
62 }
63 let total = (counter.now() - start).to_timedelta(counter.rate());
64 total.checked_div(READINGS).unwrap_or(Timedelta::ZERO)
65}