rework and document backoff behavior of sync::mpsc
· rust-lang/rust@8917e99 (original) (raw)
`@@ -91,9 +91,8 @@ impl DerefMut for CachePadded {
`
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,
`
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,12 +132,10 @@ 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
141
`self.step.get() > SPIN_LIMIT
`