Crates.io | pausable_clock |
lib.rs | pausable_clock |
version | 1.0.1 |
source | src |
created_at | 2020-08-11 01:32:35.983059 |
updated_at | 2021-06-23 02:24:10.14624 |
description | A source of time information that can be paused and resumed |
homepage | |
repository | https://github.com/RookAndPawn/pausable_clock |
max_upload_size | |
id | 275211 |
size | 70,663 |
This crate provides a clock that can be paused ... (duh?). The provided struct PausableClock
allows you to get the current time in a way that respects the atomic state and history of the clock. Put more simply, a pausable clock's elapsed time increases at the same as real time but only when the clock is resumed.
Send
/Sync
) All operations on the clock are atomic or use std mutexeswait_for_resume
method will block until the clock is resumed (if the clock is paused)std::time::Instant::now()
guarantees that time always increases, PausableClock
guarantees that the time returned by clock.now()
while the clock is paused is >= any other instant returned before the clock was paused.run_unpausable
that allows tasks to be run that can prevent the timer from being paused while they are still running.use pausable_clock::PausableClock;
use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};
let clock = Arc::new(PausableClock::default());
// With the default parameters, there should be no difference
// between the real time and the clock's time
assert!(Instant::from(clock.now()).elapsed().as_millis() == 0);
// Pause the clock right after creation
clock.pause();
// Clone the arc of the clock to pass to a new thread
let clock_clone = clock.clone();
let t = thread::spawn(move || {
// In the new thread, just wait for resume
clock_clone.wait_for_resume();
});
// Sleep for a sec, then resume the clock
thread::sleep(Duration::from_secs(1));
clock.resume();
// Wait for the spawned thread to unblock
t.join().unwrap();
// After being paused for a second, the clock is now a second behind
// (with a small error margin here because sleep is not super accurate)
assert!((Instant::from(clock.now()).elapsed().as_secs_f64() - 1.).abs() < 0.005);
AtomicU64
to contain the entire state of the pausable clock, so the granularity of the instant's produced by the clock is milliseconds. This means the maximum time the timer can handle is on the order of hundreds of thousands of years.PausableClock::is_paused
is done atomically with Ordering::Relaxed
. That allows the call to be slightly faster, but it means you shouldn't think it as fencing a operations. You can use PausableClock::is_paused_ordered
if you need that kind of guarantee.loom
-based tests.