Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 516684c

Browse files
committed
Use less restricted memory ordering in thread_parking::pthread.
SeqCst is unnecessary here.
1 parent eb96698 commit 516684c

File tree

1 file changed

+12
-10
lines changed
  • library/std/src/sys/pal/unix/thread_parking

1 file changed

+12
-10
lines changed

library/std/src/sys/pal/unix/thread_parking/pthread.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::marker::PhantomPinned;
55
use crate::pin::Pin;
66
use crate::ptr::addr_of_mut;
77
use crate::sync::atomic::AtomicUsize;
8-
use crate::sync::atomic::Ordering::SeqCst;
8+
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
99
#[cfg(not(target_os = "nto"))]
1010
use crate::sys::time::TIMESPEC_MAX;
1111
#[cfg(target_os = "nto")]
@@ -150,16 +150,18 @@ impl Parker {
150150

151151
// This implementation doesn't require `unsafe`, but other implementations
152152
// may assume this is only called by the thread that owns the Parker.
153+
//
154+
// For memory ordering, see std/src/sys_common/thread_parking/futex.rs
153155
pub unsafe fn park(self: Pin<&Self>) {
154156
// If we were previously notified then we consume this notification and
155157
// return quickly.
156-
if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() {
158+
if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed).is_ok() {
157159
return;
158160
}
159161

160162
// Otherwise we need to coordinate going to sleep
161163
lock(self.lock.get());
162-
match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
164+
match self.state.compare_exchange(EMPTY, PARKED, Relaxed, Relaxed) {
163165
Ok(_) => {}
164166
Err(NOTIFIED) => {
165167
// We must read here, even though we know it will be `NOTIFIED`.
@@ -168,7 +170,7 @@ impl Parker {
168170
// acquire operation that synchronizes with that `unpark` to observe
169171
// any writes it made before the call to unpark. To do that we must
170172
// read from the write it made to `state`.
171-
let old = self.state.swap(EMPTY, SeqCst);
173+
let old = self.state.swap(EMPTY, Acquire);
172174

173175
unlock(self.lock.get());
174176

@@ -185,7 +187,7 @@ impl Parker {
185187
loop {
186188
wait(self.cvar.get(), self.lock.get());
187189

188-
match self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) {
190+
match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) {
189191
Ok(_) => break, // got a notification
190192
Err(_) => {} // spurious wakeup, go back to sleep
191193
}
@@ -201,16 +203,16 @@ impl Parker {
201203
// Like `park` above we have a fast path for an already-notified thread, and
202204
// afterwards we start coordinating for a sleep.
203205
// return quickly.
204-
if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() {
206+
if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed).is_ok() {
205207
return;
206208
}
207209

208210
lock(self.lock.get());
209-
match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
211+
match self.state.compare_exchange(EMPTY, PARKED, Relaxed, Relaxed) {
210212
Ok(_) => {}
211213
Err(NOTIFIED) => {
212214
// We must read again here, see `park`.
213-
let old = self.state.swap(EMPTY, SeqCst);
215+
let old = self.state.swap(EMPTY, Acquire);
214216
unlock(self.lock.get());
215217

216218
assert_eq!(old, NOTIFIED, "park state changed unexpectedly");
@@ -228,7 +230,7 @@ impl Parker {
228230
// parked.
229231
wait_timeout(self.cvar.get(), self.lock.get(), dur);
230232

231-
match self.state.swap(EMPTY, SeqCst) {
233+
match self.state.swap(EMPTY, Acquire) {
232234
NOTIFIED => unlock(self.lock.get()), // got a notification, hurray!
233235
PARKED => unlock(self.lock.get()), // no notification, alas
234236
n => {
@@ -245,7 +247,7 @@ impl Parker {
245247
// `state` is already `NOTIFIED`. That is why this must be a swap
246248
// rather than a compare-and-swap that returns if it reads `NOTIFIED`
247249
// on failure.
248-
match self.state.swap(NOTIFIED, SeqCst) {
250+
match self.state.swap(NOTIFIED, Release) {
249251
EMPTY => return, // no one was waiting
250252
NOTIFIED => return, // already unparked
251253
PARKED => {} // gotta go wake someone up

0 commit comments

Comments
 (0)