1#![crate_name = "hjul"]
2#![cfg_attr(feature = "unstable", feature(test))]
3
4#[cfg(feature = "unstable")]
5extern crate test;
6
7mod timers;
8
9pub use timers::{Runner, Timer};
10
11#[cfg(test)]
12mod tests {
13 use super::*;
14 use std::sync::atomic::{AtomicBool, Ordering};
15 use std::sync::Arc;
16 use std::thread;
17 use std::time::{Duration, Instant};
18
19 #[cfg(feature = "unstable")]
20 use test::Bencher;
21
22 #[test]
25 fn test_accuracy() {
26 let capacity = 100;
27 let accuracy = Duration::from_millis(100);
28 let horrison = Duration::from_millis(10_000);
29 let cogs = (horrison.as_nanos() / accuracy.as_nanos()) as usize;
30 let runner = Runner::new(accuracy, cogs, capacity);
31
32 let tests = vec![
33 Duration::from_millis(100),
34 Duration::from_millis(200),
35 Duration::from_millis(250),
36 Duration::from_millis(200),
37 Duration::from_millis(400),
38 Duration::from_millis(600),
39 Duration::from_millis(700),
40 Duration::from_millis(100),
41 Duration::from_millis(500),
42 Duration::from_millis(500),
43 ];
44
45 let mut checks: Vec<Arc<AtomicBool>> = vec![];
47 let mut timers: Vec<Timer> = vec![];
48 for _ in 0..(capacity / tests.len()) {
49 for &dur in &tests {
50 let fired = Arc::new(AtomicBool::new(false));
51 let fcopy = fired.clone();
52 let start = Instant::now();
53 let timer = runner.timer(move || {
54 let delta = Instant::now() - start;
55 assert!(
56 delta >= dur - accuracy,
57 "at least (duration - accuracy) time should pass"
58 );
59 assert!(
60 delta + accuracy >= dur,
61 "no more than (duration + accuracy) time should pass"
62 );
63 fcopy.store(true, Ordering::SeqCst);
64 });
65 timer.reset(dur);
66 timers.push(timer);
67 checks.push(fired);
68 }
69 }
70
71 let mut longest = tests[0];
73 for &dur in &tests {
74 if dur > longest {
75 longest = dur;
76 }
77 assert!(dur < horrison);
78 }
79 thread::sleep(2 * longest);
80
81 for f in checks {
83 assert!(f.load(Ordering::Acquire));
84 }
85 }
86
87 #[cfg(feature = "unstable")]
88 #[bench]
89 fn bench_reset(b: &mut Bencher) {
90 let runner = Runner::new(Duration::from_millis(100), 100, 10);
91 let timer = runner.timer(Box::new(|| {}));
92 b.iter(|| timer.reset(Duration::from_millis(1000)));
93 }
94
95 #[cfg(feature = "unstable")]
96 #[bench]
97 fn bench_start(b: &mut Bencher) {
98 let runner = Runner::new(Duration::from_millis(100), 100, 10);
99 let timer = runner.timer(Box::new(|| {}));
100 b.iter(|| timer.start(Duration::from_millis(1000)));
101 }
102}