@@ -5,7 +5,7 @@ use crate::marker::PhantomPinned;
5
5
use crate :: pin:: Pin ;
6
6
use crate :: ptr:: addr_of_mut;
7
7
use crate :: sync:: atomic:: AtomicUsize ;
8
- use crate :: sync:: atomic:: Ordering :: SeqCst ;
8
+ use crate :: sync:: atomic:: Ordering :: { Acquire , Relaxed , Release } ;
9
9
#[ cfg( not( target_os = "nto" ) ) ]
10
10
use crate :: sys:: time:: TIMESPEC_MAX ;
11
11
#[ cfg( target_os = "nto" ) ]
@@ -150,16 +150,18 @@ impl Parker {
150
150
151
151
// This implementation doesn't require `unsafe`, but other implementations
152
152
// 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
153
155
pub unsafe fn park ( self : Pin < & Self > ) {
154
156
// If we were previously notified then we consume this notification and
155
157
// 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 ( ) {
157
159
return ;
158
160
}
159
161
160
162
// Otherwise we need to coordinate going to sleep
161
163
lock ( self . lock . get ( ) ) ;
162
- match self . state . compare_exchange ( EMPTY , PARKED , SeqCst , SeqCst ) {
164
+ match self . state . compare_exchange ( EMPTY , PARKED , Relaxed , Relaxed ) {
163
165
Ok ( _) => { }
164
166
Err ( NOTIFIED ) => {
165
167
// We must read here, even though we know it will be `NOTIFIED`.
@@ -168,7 +170,7 @@ impl Parker {
168
170
// acquire operation that synchronizes with that `unpark` to observe
169
171
// any writes it made before the call to unpark. To do that we must
170
172
// read from the write it made to `state`.
171
- let old = self . state . swap ( EMPTY , SeqCst ) ;
173
+ let old = self . state . swap ( EMPTY , Acquire ) ;
172
174
173
175
unlock ( self . lock . get ( ) ) ;
174
176
@@ -185,7 +187,7 @@ impl Parker {
185
187
loop {
186
188
wait ( self . cvar . get ( ) , self . lock . get ( ) ) ;
187
189
188
- match self . state . compare_exchange ( NOTIFIED , EMPTY , SeqCst , SeqCst ) {
190
+ match self . state . compare_exchange ( NOTIFIED , EMPTY , Acquire , Relaxed ) {
189
191
Ok ( _) => break , // got a notification
190
192
Err ( _) => { } // spurious wakeup, go back to sleep
191
193
}
@@ -201,16 +203,16 @@ impl Parker {
201
203
// Like `park` above we have a fast path for an already-notified thread, and
202
204
// afterwards we start coordinating for a sleep.
203
205
// 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 ( ) {
205
207
return ;
206
208
}
207
209
208
210
lock ( self . lock . get ( ) ) ;
209
- match self . state . compare_exchange ( EMPTY , PARKED , SeqCst , SeqCst ) {
211
+ match self . state . compare_exchange ( EMPTY , PARKED , Relaxed , Relaxed ) {
210
212
Ok ( _) => { }
211
213
Err ( NOTIFIED ) => {
212
214
// We must read again here, see `park`.
213
- let old = self . state . swap ( EMPTY , SeqCst ) ;
215
+ let old = self . state . swap ( EMPTY , Acquire ) ;
214
216
unlock ( self . lock . get ( ) ) ;
215
217
216
218
assert_eq ! ( old, NOTIFIED , "park state changed unexpectedly" ) ;
@@ -228,7 +230,7 @@ impl Parker {
228
230
// parked.
229
231
wait_timeout ( self . cvar . get ( ) , self . lock . get ( ) , dur) ;
230
232
231
- match self . state . swap ( EMPTY , SeqCst ) {
233
+ match self . state . swap ( EMPTY , Acquire ) {
232
234
NOTIFIED => unlock ( self . lock . get ( ) ) , // got a notification, hurray!
233
235
PARKED => unlock ( self . lock . get ( ) ) , // no notification, alas
234
236
n => {
@@ -245,7 +247,7 @@ impl Parker {
245
247
// `state` is already `NOTIFIED`. That is why this must be a swap
246
248
// rather than a compare-and-swap that returns if it reads `NOTIFIED`
247
249
// on failure.
248
- match self . state . swap ( NOTIFIED , SeqCst ) {
250
+ match self . state . swap ( NOTIFIED , Release ) {
249
251
EMPTY => return , // no one was waiting
250
252
NOTIFIED => return , // already unparked
251
253
PARKED => { } // gotta go wake someone up
0 commit comments