@@ -91,9 +91,8 @@ impl<T> DerefMut for CachePadded<T> {
91
91
}
92
92
93
93
const SPIN_LIMIT : u32 = 6 ;
94
- const YIELD_LIMIT : u32 = 10 ;
95
94
96
- /// Performs exponential backoff in spin loops.
95
+ /// Performs quadratic backoff in spin loops.
97
96
pub struct Backoff {
98
97
step : Cell < u32 > ,
99
98
}
@@ -104,25 +103,27 @@ impl Backoff {
104
103
Backoff { step : Cell :: new ( 0 ) }
105
104
}
106
105
107
- /// Backs off in a lock-free loop .
106
+ /// Backs off using lightweight spinning .
108
107
///
109
- /// This method should be used when we need to retry an operation because another thread made
110
- /// progress.
108
+ /// This method should be used for:
109
+ /// - Retrying an operation because another thread made progress. i.e. on CAS failure.
110
+ /// - Waiting for an operation to complete by spinning optimistically for a few iterations
111
+ /// before falling back to parking the thread (see `Backoff::is_completed`).
111
112
#[ inline]
112
- pub fn spin ( & self ) {
113
+ pub fn spin_light ( & self ) {
113
114
let step = self . step . get ( ) . min ( SPIN_LIMIT ) ;
114
115
for _ in 0 ..step. pow ( 2 ) {
115
116
crate :: hint:: spin_loop ( ) ;
116
117
}
117
118
118
- if self . step . get ( ) <= SPIN_LIMIT {
119
- self . step . set ( self . step . get ( ) + 1 ) ;
120
- }
119
+ self . step . set ( self . step . get ( ) + 1 ) ;
121
120
}
122
121
123
- /// Backs off in a blocking loop.
122
+ /// Backs off using heavyweight spinning.
123
+ ///
124
+ /// This method should be used in blocking loops where parking the thread is not an option.
124
125
#[ inline]
125
- pub fn snooze ( & self ) {
126
+ pub fn spin_heavy ( & self ) {
126
127
if self . step . get ( ) <= SPIN_LIMIT {
127
128
for _ in 0 ..self . step . get ( ) . pow ( 2 ) {
128
129
crate :: hint:: spin_loop ( )
@@ -131,14 +132,12 @@ impl Backoff {
131
132
crate :: thread:: yield_now ( ) ;
132
133
}
133
134
134
- if self . step . get ( ) <= YIELD_LIMIT {
135
- self . step . set ( self . step . get ( ) + 1 ) ;
136
- }
135
+ self . step . set ( self . step . get ( ) + 1 ) ;
137
136
}
138
137
139
- /// Returns `true` if quadratic backoff has completed and blocking the thread is advised.
138
+ /// Returns `true` if quadratic backoff has completed and parking the thread is advised.
140
139
#[ inline]
141
140
pub fn is_completed ( & self ) -> bool {
142
- self . step . get ( ) > YIELD_LIMIT
141
+ self . step . get ( ) > SPIN_LIMIT
143
142
}
144
143
}
0 commit comments