#[repr(C)]pub struct AtomicTime {
pub realtime: AtomicBool,
pub timestamp_ns: AtomicU64,
}Expand description
Represents an atomic timekeeping structure.
AtomicTime can act as a real-time clock or static clock based on its mode.
It uses an AtomicU64 to atomically update the value using only immutable
references.
The realtime flag indicates which mode the clock is currently in.
For concurrency, this struct uses atomic operations with appropriate memory orderings:
- Acquire/Release for reading/writing in static mode.
- Compare-and-exchange (
AcqRel) in real-time mode to guarantee monotonic increments.
Fields§
§realtime: AtomicBoolIndicates whether the clock is operating in real-time mode (true) or static mode (false)
timestamp_ns: AtomicU64The last recorded time (in UNIX nanoseconds). Updated atomically with compare-and-exchange in real-time mode, or simple store/fetch in static mode.
Implementations§
Source§impl AtomicTime
impl AtomicTime
Sourcepub fn new(realtime: bool, time: UnixNanos) -> Self
pub fn new(realtime: bool, time: UnixNanos) -> Self
Creates a new AtomicTime instance.
- If
realtimeistrue, the providedtimeis used only as an initial placeholder and will quickly be overridden by calls toAtomicTime::time_since_epoch. - If
realtimeisfalse, this clock starts in static mode, with the giventimeas its current value.
Sourcepub fn get_time_ns(&self) -> UnixNanos
pub fn get_time_ns(&self) -> UnixNanos
Returns the current time in nanoseconds, based on the clock’s mode.
- In real-time mode, calls
AtomicTime::time_since_epoch, ensuring strictly increasing timestamps across threads, usingAcqRelsemantics for the underlying atomic. - In static mode, reads the stored time using
Ordering::Acquire. Updates by other threads usingAtomicTime::set_timeorAtomicTime::increment_time(Release/AcqRel) will be visible here.
§Thread Safety
The mode check is not atomic with the subsequent read/update. If another thread switches modes between the check and the operation, one stale-mode result may be returned. This is intentional: mode switching is a setup-time operation and should not occur concurrently with time operations.
Sourcepub fn get_time_us(&self) -> u64
pub fn get_time_us(&self) -> u64
Returns the current time as microseconds.
Sourcepub fn get_time_ms(&self) -> u64
pub fn get_time_ms(&self) -> u64
Returns the current time as milliseconds.
Sourcepub fn set_time(&self, time: UnixNanos)
pub fn set_time(&self, time: UnixNanos)
Manually sets a new time for the clock (only possible in static mode).
This uses an atomic store with Ordering::Release, so any thread reading with
Ordering::Acquire will see the updated time. This does not enforce a total ordering
among all threads, but is enough to ensure that once a thread sees this update, it also
sees all writes made before this call in the writing thread.
Typically used in single-threaded scenarios or coordinated concurrency in static mode, since there’s no global ordering across threads.
§Panics
Panics if invoked when in real-time mode.
§Thread Safety
The mode check is not atomic with the subsequent store. If another thread calls
make_realtime() between the check and store, the invariant can be violated.
This is intentional: mode switching is a setup-time operation and should not
occur concurrently with time operations. Callers must ensure mode switches are
complete before resuming time operations.
Sourcepub fn increment_time(&self, delta: u64) -> Result<UnixNanos>
pub fn increment_time(&self, delta: u64) -> Result<UnixNanos>
Increments the current (static-mode) time by delta nanoseconds and returns the updated value.
Internally this uses AtomicU64::fetch_update with Ordering::AcqRel to ensure the increment is
atomic and visible to readers using Acquire loads.
§Errors
Returns an error if the increment would overflow u64::MAX or if called
while the clock is in real-time mode.
§Thread Safety
The mode check is not atomic with the subsequent update. If another thread calls
make_realtime() between the check and update, the invariant can be violated.
This is intentional: mode switching is a setup-time operation and should not
occur concurrently with time operations. Callers must ensure mode switches are
complete before resuming time operations.
Sourcepub fn time_since_epoch(&self) -> UnixNanos
pub fn time_since_epoch(&self) -> UnixNanos
Retrieves and updates the current “real-time” clock, returning a strictly increasing timestamp based on system time.
Internally:
- We fetch
nowfromSystemTime::now(). - We do an atomic compare-and-exchange (using
Ordering::AcqRel) to ensure the stored timestamp is never less than the last timestamp.
This ensures:
- Monotonic increments: The returned timestamp is strictly greater than the previous one (by at least 1 nanosecond).
- No backward jumps: If the OS time moves backward, we ignore that shift to preserve monotonicity.
- Visibility: In a multi-threaded environment, other threads see the updated value once this compare-and-exchange completes.
§Panics
Panics if the internal counter has reached u64::MAX, which would indicate the process has
been running for longer than the representable range (~584 years) or the clock was
manually corrupted.
Sourcepub fn make_realtime(&self)
pub fn make_realtime(&self)
Switches the clock to real-time mode (realtime = true).
If transitioning from static mode, the internal counter is reset to the current
wall-clock time so that AtomicTime::time_since_epoch does not carry forward a
timestamp set during static mode (e.g. a backtest far in the future).
Uses Ordering::SeqCst for the mode flag to ensure global ordering.
Sourcepub fn make_static(&self)
pub fn make_static(&self)
Switches the clock to static mode (realtime = false).
If transitioning from real-time mode, the internal counter is snapshotted to the current wall-clock time so that subsequent static reads return a reasonable value rather than a stale or zero placeholder.
Uses Ordering::SeqCst for the mode flag to ensure global ordering.
Trait Implementations§
Source§impl Debug for AtomicTime
impl Debug for AtomicTime
Source§impl Default for AtomicTime
impl Default for AtomicTime
Source§fn default() -> Self
fn default() -> Self
Creates a new default AtomicTime instance in real-time mode, starting at the current system time.
Auto Trait Implementations§
impl !Freeze for AtomicTime
impl RefUnwindSafe for AtomicTime
impl Send for AtomicTime
impl Sync for AtomicTime
impl Unpin for AtomicTime
impl UnsafeUnpin for AtomicTime
impl UnwindSafe for AtomicTime
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more