@@ -5,7 +5,7 @@ use crate::marker::PhantomPinned;
55use crate :: pin:: Pin ;
66use crate :: ptr:: addr_of_mut;
77use 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" ) ) ]
1010use 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