static_init/phase_locker/
spin_wait.rs1use core::hint;
2#[inline]
5fn cpu_relax(iterations: u32) {
6 for _ in 0..iterations {
7 hint::spin_loop()
8 }
9}
10
11#[derive(Default)]
13pub(super) struct SpinWait {
14 counter: u32,
15}
16
17impl SpinWait {
18 #[inline]
20 pub fn new() -> Self {
21 Self::default()
22 }
23
24 #[inline]
26 #[cfg(not(feature = "spin_loop"))]
27 pub fn reset(&mut self) {
28 self.counter = 0;
29 }
30
31 #[inline]
40 #[cfg(not(feature = "spin_loop"))]
41 pub fn spin(&mut self) -> bool {
42 if self.counter >= 10
43 {
45 return false;
46 }
47 self.counter += 1;
48
49 if self.counter <= 3
50 {
52 cpu_relax(1 << self.counter);
53 } else {
54 yield_now();
55 }
56 true
57 }
58
59 #[inline]
65 pub fn spin_no_yield(&mut self) -> bool {
66 self.counter += 1;
67 if self.counter > 10 {
68 self.counter = 10;
69 }
70 cpu_relax(1 << self.counter);
71 true
72 }
73}
74
75#[cfg(all(
76 not(feature = "parking_lot_core"),
77 not(feature = "spin_loop"),
78 any(target_os = "linux", target_os = "android")
79))]
80fn yield_now() {
81 unsafe {
82 libc::sched_yield();
83 }
84}
85#[cfg(all(
86 not(feature = "spin_loop"),
87 not(all(
88 not(feature = "parking_lot_core"),
89 any(target_os = "linux", target_os = "android")
90 ))
91))]
92use std::thread::yield_now;