Skip to main content

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}