use alloc::sync::Arc;
use alloc::vec::Vec;
use core::sync::atomic::{AtomicU64, Ordering};
use crate::channel::Subscriber;
use crate::pod::Pod;
use crate::ring::Padded;
pub struct DependencyBarrier {
upstreams: Vec<Arc<Padded<AtomicU64>>>,
}
impl DependencyBarrier {
pub fn new(trackers: Vec<Arc<Padded<AtomicU64>>>) -> Self {
assert!(
!trackers.is_empty(),
"DependencyBarrier requires at least one upstream tracker"
);
DependencyBarrier {
upstreams: trackers,
}
}
pub fn from_subscribers<T: Pod>(subscribers: &[&Subscriber<T>]) -> Self {
assert!(
!subscribers.is_empty(),
"DependencyBarrier requires at least one upstream subscriber"
);
let trackers: Vec<Arc<Padded<AtomicU64>>> = subscribers
.iter()
.map(|s| {
s.tracker()
.expect("upstream subscriber has no tracker — use subscribe_tracked()")
})
.collect();
DependencyBarrier {
upstreams: trackers,
}
}
#[inline]
pub fn slowest(&self) -> u64 {
let mut min = u64::MAX;
for t in &self.upstreams {
let val = t.0.load(Ordering::Acquire);
if val < min {
min = val;
}
}
min
}
#[inline]
pub fn upstream_count(&self) -> usize {
self.upstreams.len()
}
}