qubit_clock/monotonic/std_monotonic_clock.rs
1// =============================================================================
2// Copyright (c) 2025 - 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Defines the standard-library monotonic clock implementation.
9
10use std::sync::Arc;
11use std::time::Instant;
12
13use crate::ClockDomain;
14use crate::MonotonicClock;
15use crate::MonotonicInstant;
16use crate::StdTimer;
17use crate::Timer;
18
19/// A real monotonic clock backed by [`std::time::Instant`].
20///
21/// The type intentionally does not implement [`Clone`]. Shared identity is
22/// expressed explicitly with `Arc<StdMonotonicClock>`.
23#[derive(Debug)]
24pub struct StdMonotonicClock {
25 /// Domain carried by instants sampled from this clock.
26 domain: ClockDomain,
27 /// Native standard-library instant mapped to elapsed duration zero.
28 origin: Instant,
29}
30
31impl StdMonotonicClock {
32 /// Creates a new independent clock domain at the current native instant.
33 ///
34 /// # Returns
35 ///
36 /// A standard monotonic clock with a newly allocated domain.
37 ///
38 /// # Panics
39 ///
40 /// Panics if all process-wide clock-domain identifiers are exhausted.
41 #[must_use]
42 #[inline]
43 pub fn new() -> Self {
44 Self {
45 domain: ClockDomain::new(),
46 origin: Instant::now(),
47 }
48 }
49
50 /// Creates a private handle retaining this exact standard clock domain.
51 ///
52 /// # Returns
53 ///
54 /// A clock handle with the same domain identifier and native origin.
55 #[must_use]
56 #[inline]
57 pub(crate) const fn same_domain_handle(&self) -> Self {
58 Self {
59 domain: self.domain,
60 origin: self.origin,
61 }
62 }
63
64 /// Returns the native origin used by a paired standard timer.
65 ///
66 /// # Returns
67 ///
68 /// The standard-library instant mapped to elapsed duration zero.
69 #[must_use]
70 #[inline(always)]
71 pub(crate) const fn origin(&self) -> Instant {
72 self.origin
73 }
74
75 /// Returns this concrete clock's domain without sampling native time.
76 ///
77 /// # Returns
78 ///
79 /// This clock's process-unique domain.
80 #[inline(always)]
81 pub(crate) const fn domain(&self) -> ClockDomain {
82 self.domain
83 }
84}
85
86impl Default for StdMonotonicClock {
87 /// Creates a new independent standard monotonic clock domain.
88 ///
89 /// # Returns
90 ///
91 /// A standard monotonic clock with a newly allocated domain.
92 ///
93 /// # Panics
94 ///
95 /// Panics if all process-wide clock-domain identifiers are exhausted.
96 #[inline(always)]
97 fn default() -> Self {
98 Self::new()
99 }
100}
101
102impl MonotonicClock for StdMonotonicClock {
103 /// Returns this clock's stable monotonic domain identity.
104 ///
105 /// # Returns
106 ///
107 /// This clock's process-unique domain.
108 #[inline(always)]
109 fn domain(&self) -> ClockDomain {
110 self.domain
111 }
112
113 /// Returns the current instant in this clock's domain.
114 ///
115 /// # Returns
116 ///
117 /// The current elapsed duration represented in this clock's domain.
118 #[inline]
119 fn now(&self) -> MonotonicInstant {
120 MonotonicInstant::new(self.domain, self.origin.elapsed())
121 }
122
123 /// Creates a timer retaining this exact standard clock domain and origin.
124 ///
125 /// # Returns
126 ///
127 /// A shared timer backed by one lazy standard scheduler worker.
128 #[inline]
129 fn new_timer(&self) -> Arc<dyn Timer> {
130 Arc::new(StdTimer::from_clock(self))
131 }
132}