spinning_top/relax.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
//! Relax strategies.
//!
//! Relax strategies are used when the thread cannot acquire a spinlock.
/// A relax strategy.
///
/// `Relax` types are used to relax the current thread during contention.
pub trait Relax: Default {
/// Relaxes the current thread.
fn relax(&mut self);
}
/// Rapid spinning.
///
/// This emits [`core::hint::spin_loop`].
#[derive(Default, Debug)]
pub struct Spin;
impl Relax for Spin {
#[inline]
fn relax(&mut self) {
core::hint::spin_loop();
}
}
/// Exponential backoff.
///
/// This performs exponential backoff to avoid unnecessarily stressing the cache.
//Adapted from <https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.16/crossbeam-utils/src/backoff.rs>.
#[derive(Default, Debug)]
pub struct Backoff {
step: u8,
}
impl Backoff {
const YIELD_LIMIT: u8 = 10;
}
impl Relax for Backoff {
#[inline]
fn relax(&mut self) {
for _ in 0..1_u16 << self.step {
core::hint::spin_loop();
}
if self.step <= Self::YIELD_LIMIT {
self.step += 1;
}
}
}