@@ -255,6 +255,9 @@ fn join_orders_after_tls_destructors() {
255255 // observe the channel in the `THREAD1_WAITING` state. If this does occur,
256256 // we switch to the “poison” state `THREAD2_JOINED` and panic all around.
257257 // (This is equivalent to “sending” from an alternate producer thread.)
258+ //
259+ // Relaxed memory ordering is fine because and spawn()/join() already provide all the
260+ // synchronization we need here.
258261 const FRESH : u8 = 0 ;
259262 const THREAD2_LAUNCHED : u8 = 1 ;
260263 const THREAD1_WAITING : u8 = 2 ;
@@ -263,7 +266,7 @@ fn join_orders_after_tls_destructors() {
263266 static SYNC_STATE : AtomicU8 = AtomicU8 :: new ( FRESH ) ;
264267
265268 for _ in 0 ..10 {
266- SYNC_STATE . store ( FRESH , Ordering :: SeqCst ) ;
269+ SYNC_STATE . store ( FRESH , Ordering :: Relaxed ) ;
267270
268271 let jh = thread:: Builder :: new ( )
269272 . name ( "thread1" . into ( ) )
@@ -272,7 +275,7 @@ fn join_orders_after_tls_destructors() {
272275
273276 impl Drop for TlDrop {
274277 fn drop ( & mut self ) {
275- let mut sync_state = SYNC_STATE . swap ( THREAD1_WAITING , Ordering :: SeqCst ) ;
278+ let mut sync_state = SYNC_STATE . swap ( THREAD1_WAITING , Ordering :: Relaxed ) ;
276279 loop {
277280 match sync_state {
278281 THREAD2_LAUNCHED | THREAD1_WAITING => thread:: yield_now ( ) ,
@@ -282,7 +285,7 @@ fn join_orders_after_tls_destructors() {
282285 ) ,
283286 v => unreachable ! ( "sync state: {}" , v) ,
284287 }
285- sync_state = SYNC_STATE . load ( Ordering :: SeqCst ) ;
288+ sync_state = SYNC_STATE . load ( Ordering :: Relaxed ) ;
286289 }
287290 }
288291 }
@@ -294,7 +297,7 @@ fn join_orders_after_tls_destructors() {
294297 TL_DROP . with ( |_| { } ) ;
295298
296299 loop {
297- match SYNC_STATE . load ( Ordering :: SeqCst ) {
300+ match SYNC_STATE . load ( Ordering :: Relaxed ) {
298301 FRESH => thread:: yield_now ( ) ,
299302 THREAD2_LAUNCHED => break ,
300303 v => unreachable ! ( "sync state: {}" , v) ,
@@ -306,9 +309,9 @@ fn join_orders_after_tls_destructors() {
306309 let jh2 = thread:: Builder :: new ( )
307310 . name ( "thread2" . into ( ) )
308311 . spawn ( move || {
309- assert_eq ! ( SYNC_STATE . swap( THREAD2_LAUNCHED , Ordering :: SeqCst ) , FRESH ) ;
312+ assert_eq ! ( SYNC_STATE . swap( THREAD2_LAUNCHED , Ordering :: Relaxed ) , FRESH ) ;
310313 jh. join ( ) . unwrap ( ) ;
311- match SYNC_STATE . swap ( THREAD2_JOINED , Ordering :: SeqCst ) {
314+ match SYNC_STATE . swap ( THREAD2_JOINED , Ordering :: Relaxed ) {
312315 MAIN_THREAD_RENDEZVOUS => return ,
313316 THREAD2_LAUNCHED | THREAD1_WAITING => {
314317 panic ! ( "Thread 2 running after thread 1 join before main thread rendezvous" )
@@ -322,8 +325,8 @@ fn join_orders_after_tls_destructors() {
322325 match SYNC_STATE . compare_exchange (
323326 THREAD1_WAITING ,
324327 MAIN_THREAD_RENDEZVOUS ,
325- Ordering :: SeqCst ,
326- Ordering :: SeqCst ,
328+ Ordering :: Relaxed ,
329+ Ordering :: Relaxed ,
327330 ) {
328331 Ok ( _) => break ,
329332 Err ( FRESH ) => thread:: yield_now ( ) ,
0 commit comments