1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; pub type Time = usize; pub struct Clock { counter: AtomicUsize } impl Clock { pub fn new() -> Clock { 0.into() } pub fn time(&self) -> Time { self.counter.load(Ordering::SeqCst) } pub fn increment(&self) -> Time { self.counter.fetch_add(1, Ordering::SeqCst)+1 } pub fn witness(&self, other: Time) { loop { let cur = self.counter.load(Ordering::SeqCst); if other < cur { return; } if self.counter.compare_and_swap(cur, other+1, Ordering::SeqCst) == cur { return } } } } impl From<usize> for Clock { fn from(t: usize) -> Clock { Clock{ counter: AtomicUsize::new(t) } } } impl Iterator for Clock { type Item = Time; fn next(&mut self) -> Option<Self::Item> { Some(self.increment()) } } #[test] fn increment_test() { let clk: Clock = 0.into(); assert!(clk.time() == 0); assert!(clk.increment() == 1); } #[test] fn iter_test() { let mut clk: Clock = 0.into(); assert!(clk.next().unwrap() == 1); assert!(clk.next().unwrap() == 2); assert!(clk.next().unwrap() == 3); } #[test] fn witness_test() { let clk: Clock = 0.into(); let t2: Time = 5; clk.witness(t2); assert!(clk.time() == 6); } #[test] fn sync_test() { fn is_sync<T>(_: T) -> bool where T: Sync { true } assert!(is_sync(Clock::new())) }