-
Notifications
You must be signed in to change notification settings - Fork 0
/
clock.rs
61 lines (55 loc) · 1.48 KB
/
clock.rs
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
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};
use crate::core::ports::OutputPin;
use crate::core::AsyncComponent;
pub struct Clock {
interval: Duration,
output: OutputPin,
}
impl Clock {
pub fn new(ticks_per_second: u64) -> Self {
Self {
interval: Duration::from_nanos(1_000_000_000 / ticks_per_second / 2),
output: OutputPin::new(),
}
}
pub fn state(&self) -> bool {
self.output.value()
}
pub fn output(&mut self) -> &mut OutputPin {
&mut self.output
}
}
impl AsyncComponent for Clock {
fn run(&mut self, stop: Arc<AtomicBool>) {
let start = Instant::now();
let time;
let mut next_tick = Instant::now() + self.interval;
let mut tick_count = 0;
let mut now;
loop {
while {
now = Instant::now();
now
} < next_tick
{
thread::sleep(next_tick - now);
}
next_tick += self.interval;
tick_count += 1;
if stop.load(Ordering::Relaxed) {
time = start.elapsed();
break;
}
self.output.send(!self.output.value());
}
println!(
"Clock: {} ticks in {} ms, speed {} MHz",
tick_count,
time.as_millis(),
tick_count as f64 / time.as_micros() as f64
);
}
}