use core::hint;
#[inline]
fn cpu_relax(iterations: u32) {
for _ in 0..iterations {
hint::spin_loop()
}
}
#[derive(Default)]
pub(super) struct SpinWait {
counter: u32,
}
impl SpinWait {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
#[cfg(not(feature = "spin_loop"))]
pub fn reset(&mut self) {
self.counter = 0;
}
#[inline]
#[cfg(not(feature = "spin_loop"))]
pub fn spin(&mut self) -> bool {
if self.counter >= 10
{
return false;
}
self.counter += 1;
if self.counter <= 3
{
cpu_relax(1 << self.counter);
} else {
yield_now();
}
true
}
#[inline]
pub fn spin_no_yield(&mut self) -> bool {
self.counter += 1;
if self.counter > 10 {
self.counter = 10;
}
cpu_relax(1 << self.counter);
true
}
}
#[cfg(all(
not(feature = "parking_lot_core"),
not(feature = "spin_loop"),
any(target_os = "linux", target_os = "android")
))]
fn yield_now() {
unsafe {
libc::sched_yield();
}
}
#[cfg(all(
not(feature = "spin_loop"),
not(all(
not(feature = "parking_lot_core"),
any(target_os = "linux", target_os = "android")
))
))]
use std::thread::yield_now;