#[derive(Debug, Copy, Clone)]
pub struct Backoff {
exp: u8,
max: u8,
}
impl Backoff {
pub const DEFAULT_MAX_EXPONENT: u8 = 8;
#[must_use]
pub const fn new() -> Self {
Self {
exp: 0,
max: Self::DEFAULT_MAX_EXPONENT,
}
}
#[must_use]
pub fn with_max_exponent(max: u8) -> Self {
assert!(max <= Self::DEFAULT_MAX_EXPONENT);
Self { exp: 0, max }
}
#[inline(always)]
pub fn spin(&mut self) {
#[cfg_attr(loom, allow(unused_variables))]
let spins = 1 << self.exp;
#[cfg(not(loom))]
for _ in 0..spins {
crate::loom::hint::spin_loop();
}
#[cfg(loom)]
{
test_debug!("would back off for {spins} spins");
loom::thread::yield_now();
}
if self.exp < self.max {
self.exp += 1
}
}
}
impl Default for Backoff {
fn default() -> Self {
Self::new()
}
}