#[inline]
pub fn wait_backoff(iteration: &mut u32) {
let i = *iteration;
if i < 100 {
core::hint::spin_loop();
} else if i < 1000 {
let pauses = ((i - 100) >> 3) + 1;
for _ in 0..pauses.min(32) {
core::hint::spin_loop();
}
} else {
if i % 16 == 0 {
std::thread::yield_now();
} else {
core::hint::spin_loop();
}
}
*iteration = iteration.wrapping_add(1);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_backoff_progression() {
let mut iter = 0;
for _ in 0..100 {
wait_backoff(&mut iter);
}
assert_eq!(iter, 100);
for _ in 0..900 {
wait_backoff(&mut iter);
}
assert_eq!(iter, 1000);
for _ in 0..100 {
wait_backoff(&mut iter);
}
assert_eq!(iter, 1100);
}
#[test]
fn test_wrapping() {
let mut iter = u32::MAX;
wait_backoff(&mut iter);
assert_eq!(iter, 0); }
}