trueno/brick/patterns/
dual_waker_state.rs1#[derive(Debug, Default)]
8pub struct DualWakerState {
9 producer_waiting: bool,
11 consumer_waiting: bool,
13 fill_percent: u8,
15 high_watermark: u8,
17 low_watermark: u8,
19}
20
21impl DualWakerState {
22 pub fn new(low_watermark: u8, high_watermark: u8) -> Self {
24 Self {
25 producer_waiting: false,
26 consumer_waiting: false,
27 fill_percent: 0,
28 high_watermark: high_watermark.min(100),
29 low_watermark: low_watermark.min(high_watermark),
30 }
31 }
32
33 pub fn update_fill(&mut self, fill_percent: u8) -> WakeDecision {
35 let old_fill = self.fill_percent;
36 self.fill_percent = fill_percent.min(100);
37
38 if old_fill < self.high_watermark && self.fill_percent >= self.high_watermark {
40 return WakeDecision::PauseProducer;
41 }
42
43 if old_fill > self.low_watermark && self.fill_percent <= self.low_watermark {
45 return WakeDecision::WakeProducer;
46 }
47
48 if self.fill_percent > 0 && self.consumer_waiting {
50 return WakeDecision::WakeConsumer;
51 }
52
53 WakeDecision::None
54 }
55
56 pub fn producer_wait(&mut self) {
58 self.producer_waiting = true;
59 }
60
61 pub fn consumer_wait(&mut self) {
63 self.consumer_waiting = true;
64 }
65
66 pub fn producer_woke(&mut self) {
68 self.producer_waiting = false;
69 }
70
71 pub fn consumer_woke(&mut self) {
73 self.consumer_waiting = false;
74 }
75
76 #[must_use]
78 pub fn can_produce(&self) -> bool {
79 self.fill_percent < self.high_watermark
80 }
81
82 #[must_use]
84 pub fn can_consume(&self) -> bool {
85 self.fill_percent > 0
86 }
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq)]
91pub enum WakeDecision {
92 None,
94 WakeProducer,
96 WakeConsumer,
98 PauseProducer,
100}