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