use std::sync::{Arc, Mutex, Weak};
pub struct DeviceClock {
freq_hz: u64,
enabled: bool,
children: Vec<Weak<Mutex<DeviceClock>>>,
pub multiplier: u64,
pub divider: u64,
}
impl DeviceClock {
pub fn new(freq_hz: u64) -> Self {
Self {
freq_hz,
enabled: true,
children: Vec::new(),
multiplier: 1,
divider: 1,
}
}
pub fn freq_hz(&self) -> u64 {
self.freq_hz
}
pub fn set_freq(&mut self, freq_hz: u64) {
self.freq_hz = freq_hz;
}
pub fn enabled(&self) -> bool {
self.enabled
}
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
pub fn period_ns(&self) -> u64 {
if self.freq_hz == 0 {
return 0;
}
1_000_000_000 / self.freq_hz
}
pub fn add_child(&mut self, child: &Arc<Mutex<DeviceClock>>) {
self.children.retain(|w| w.strong_count() > 0);
self.children.push(Arc::downgrade(child));
}
pub fn propagate(&self) {
for weak in &self.children {
if let Some(arc) = weak.upgrade() {
let mut child = arc.lock().unwrap();
child.freq_hz = self.freq_hz * child.multiplier / child.divider;
child.propagate();
}
}
}
pub fn set_freq_and_propagate(&mut self, freq: u64) {
self.freq_hz = freq;
self.propagate();
}
}