#[derive(Debug, Default)]
pub struct DualWakerState {
producer_waiting: bool,
consumer_waiting: bool,
fill_percent: u8,
high_watermark: u8,
low_watermark: u8,
}
impl DualWakerState {
pub fn new(low_watermark: u8, high_watermark: u8) -> Self {
Self {
producer_waiting: false,
consumer_waiting: false,
fill_percent: 0,
high_watermark: high_watermark.min(100),
low_watermark: low_watermark.min(high_watermark),
}
}
pub fn update_fill(&mut self, fill_percent: u8) -> WakeDecision {
let old_fill = self.fill_percent;
self.fill_percent = fill_percent.min(100);
if old_fill < self.high_watermark && self.fill_percent >= self.high_watermark {
return WakeDecision::PauseProducer;
}
if old_fill > self.low_watermark && self.fill_percent <= self.low_watermark {
return WakeDecision::WakeProducer;
}
if self.fill_percent > 0 && self.consumer_waiting {
return WakeDecision::WakeConsumer;
}
WakeDecision::None
}
pub fn producer_wait(&mut self) {
self.producer_waiting = true;
}
pub fn consumer_wait(&mut self) {
self.consumer_waiting = true;
}
pub fn producer_woke(&mut self) {
self.producer_waiting = false;
}
pub fn consumer_woke(&mut self) {
self.consumer_waiting = false;
}
#[must_use]
pub fn can_produce(&self) -> bool {
self.fill_percent < self.high_watermark
}
#[must_use]
pub fn can_consume(&self) -> bool {
self.fill_percent > 0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WakeDecision {
None,
WakeProducer,
WakeConsumer,
PauseProducer,
}