Skip to main content

LiveClock_API

Struct LiveClock_API 

Source
pub struct LiveClock_API(/* private fields */);
Expand description

C compatible Foreign Function Interface (FFI) for an underlying LiveClock.

This struct wraps LiveClock in a way that makes it compatible with C function calls, enabling interaction with LiveClock in a C environment.

It implements the Deref and DerefMut traits, allowing instances of LiveClock_API to be dereferenced to LiveClock, providing access to LiveClock’s methods without having to manually access the underlying LiveClock instance. This includes both mutable and immutable access.

Methods from Deref<Target = LiveClock>§

Source

pub fn get_timers(&self) -> &BTreeMap<Ustr, LiveTimer>

Methods from Deref<Target = AtomicTime>§

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, using AcqRel semantics for the underlying atomic.
  • In static mode, reads the stored time using Ordering::Acquire. Updates by other threads using [AtomicTime::set_time] or [AtomicTime::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.

pub fn get_time_us(&self) -> u64

Returns the current time as microseconds.

pub fn get_time_ms(&self) -> u64

Returns the current time as milliseconds.

pub fn get_time(&self) -> f64

Returns the current time as seconds.

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.

pub fn increment_time(&self, delta: u64) -> Result<UnixNanos, Error>

Increments the current (static-mode) time by delta nanoseconds and returns the updated value.

Internally this uses AtomicU64::try_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.

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 now from SystemTime::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:

  1. Monotonic increments: The returned timestamp is strictly greater than the previous one (by at least 1 nanosecond).
  2. No backward jumps: If the OS time moves backward, we ignore that shift to preserve monotonicity.
  3. 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.

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.

§Thread Safety

The mode swap and the counter reset are two separate atomic operations. A thread reading between them can observe real-time mode with the stale static-mode counter and return a timestamp derived from it (potentially far in the future), after which the reset moves the clock backwards. Mode switching is a setup-time operation and must not run concurrently with time reads.

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.

§Thread Safety

The mode swap and the counter snapshot are two separate atomic operations; see [AtomicTime::make_realtime] for the race this implies. Mode switching is a setup-time operation and must not run concurrently with time reads.

Trait Implementations§

Source§

impl Debug for LiveClock_API

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for LiveClock_API

Source§

type Target = LiveClock

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl DerefMut for LiveClock_API

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Ungil for T
where T: Send,

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more