pub struct TestClock_API(/* private fields */);Expand description
C compatible Foreign Function Interface (FFI) for an underlying TestClock.
This struct wraps TestClock in a way that makes it compatible with C function
calls, enabling interaction with TestClock in a C environment.
It implements the Deref trait, allowing instances of TestClock_API to be
dereferenced to TestClock, providing access to TestClock’s methods without
having to manually access the underlying TestClock instance.
Methods from Deref<Target = TestClock>§
Sourcepub fn get_timers(&self) -> &BTreeMap<Ustr, TestTimer>
pub fn get_timers(&self) -> &BTreeMap<Ustr, TestTimer>
Returns a reference to the internal timers for the clock.
Sourcepub fn advance_time(
&mut self,
to_time_ns: UnixNanos,
set_time: bool,
) -> Vec<TimeEvent>
pub fn advance_time( &mut self, to_time_ns: UnixNanos, set_time: bool, ) -> Vec<TimeEvent>
Advances the internal clock to the specified to_time_ns and optionally sets the clock to that time.
This function ensures that the clock behaves in a non-decreasing manner. If set_time is true,
the internal clock will be updated to the value of to_time_ns. Otherwise, the clock will advance
without explicitly setting the time.
The method processes active timers, advancing them to to_time_ns, and collects any TimeEvent
objects that are triggered as a result. Only timers that are not expired are processed.
§Warnings
Logs a warning if >= 1,000,000 time events are allocated during advancement.
§Panics
Panics if to_time_ns is less than the current internal clock time.
Sourcepub fn match_handlers(&self, events: Vec<TimeEvent>) -> Vec<TimeEventHandler>
pub fn match_handlers(&self, events: Vec<TimeEvent>) -> Vec<TimeEventHandler>
Matches TimeEvent objects with their corresponding event handlers.
This function takes an events vector of TimeEvent objects, assumes they are already sorted
by their ts_event, and matches them with the appropriate callback handler from the internal
registry of callbacks. If no specific callback is found for an event, the default callback is used.
§Panics
Panics if the default callback is not set for the clock when matching handlers.
Methods from Deref<Target = AtomicTime>§
pub 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 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
pub fn get_time_us(&self) -> u64
Returns the current time as microseconds.
pub fn get_time_ms(&self) -> u64
pub fn get_time_ms(&self) -> u64
Returns the current time as milliseconds.
pub 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.
pub fn increment_time(&self, delta: u64) -> Result<UnixNanos, Error>
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
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.
pub 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.
§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)
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.