#[derive(Debug, Default)]
pub struct WakeSkipState {
pending_items: usize,
has_waker: bool,
last_poll_had_work: bool,
empty_poll_count: u32,
skip_threshold: u32,
}
impl WakeSkipState {
pub fn new(skip_threshold: u32) -> Self {
Self {
pending_items: 0,
has_waker: false,
last_poll_had_work: false,
empty_poll_count: 0,
skip_threshold,
}
}
pub fn register_waker(&mut self) {
self.has_waker = true;
}
pub fn clear_waker(&mut self) {
self.has_waker = false;
}
pub fn add_pending(&mut self, count: usize) {
self.pending_items += count;
}
pub fn remove_pending(&mut self, count: usize) {
self.pending_items = self.pending_items.saturating_sub(count);
}
pub fn record_poll(&mut self, had_work: bool) {
self.last_poll_had_work = had_work;
if had_work {
self.empty_poll_count = 0;
} else {
self.empty_poll_count += 1;
}
}
#[must_use]
pub fn should_skip_wake(&self) -> bool {
if !self.has_waker {
return true;
}
if self.pending_items > 0 && self.last_poll_had_work {
return true; }
if self.empty_poll_count >= self.skip_threshold {
return true; }
false
}
#[must_use]
pub fn needs_wake(&self) -> bool {
!self.should_skip_wake() && self.pending_items > 0
}
#[must_use]
pub fn pending(&self) -> usize {
self.pending_items
}
pub fn reset_tracking(&mut self) {
self.empty_poll_count = 0;
}
}