trueno/brick/patterns/
wake_skip_state.rs1#[derive(Debug, Default)]
8pub struct WakeSkipState {
9 pending_items: usize,
11 has_waker: bool,
13 last_poll_had_work: bool,
15 empty_poll_count: u32,
17 skip_threshold: u32,
19}
20
21impl WakeSkipState {
22 pub fn new(skip_threshold: u32) -> Self {
24 Self {
25 pending_items: 0,
26 has_waker: false,
27 last_poll_had_work: false,
28 empty_poll_count: 0,
29 skip_threshold,
30 }
31 }
32
33 pub fn register_waker(&mut self) {
35 self.has_waker = true;
36 }
37
38 pub fn clear_waker(&mut self) {
40 self.has_waker = false;
41 }
42
43 pub fn add_pending(&mut self, count: usize) {
45 self.pending_items += count;
46 }
47
48 pub fn remove_pending(&mut self, count: usize) {
50 self.pending_items = self.pending_items.saturating_sub(count);
51 }
52
53 pub fn record_poll(&mut self, had_work: bool) {
55 self.last_poll_had_work = had_work;
56 if had_work {
57 self.empty_poll_count = 0;
58 } else {
59 self.empty_poll_count += 1;
60 }
61 }
62
63 #[must_use]
65 pub fn should_skip_wake(&self) -> bool {
66 if !self.has_waker {
71 return true;
72 }
73 if self.pending_items > 0 && self.last_poll_had_work {
74 return true; }
76 if self.empty_poll_count >= self.skip_threshold {
77 return true; }
79 false
80 }
81
82 #[must_use]
84 pub fn needs_wake(&self) -> bool {
85 !self.should_skip_wake() && self.pending_items > 0
86 }
87
88 #[must_use]
90 pub fn pending(&self) -> usize {
91 self.pending_items
92 }
93
94 pub fn reset_tracking(&mut self) {
96 self.empty_poll_count = 0;
97 }
98}