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

`