@@ -255,6 +255,9 @@ fn join_orders_after_tls_destructors() {
255
255
// observe the channel in the `THREAD1_WAITING` state. If this does occur,
256
256
// we switch to the “poison” state `THREAD2_JOINED` and panic all around.
257
257
// (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.
258
261
const FRESH : u8 = 0 ;
259
262
const THREAD2_LAUNCHED : u8 = 1 ;
260
263
const THREAD1_WAITING : u8 = 2 ;
@@ -263,7 +266,7 @@ fn join_orders_after_tls_destructors() {
263
266
static SYNC_STATE : AtomicU8 = AtomicU8 :: new ( FRESH ) ;
264
267
265
268
for _ in 0 ..10 {
266
- SYNC_STATE . store ( FRESH , Ordering :: SeqCst ) ;
269
+ SYNC_STATE . store ( FRESH , Ordering :: Relaxed ) ;
267
270
268
271
let jh = thread:: Builder :: new ( )
269
272
. name ( "thread1" . into ( ) )
@@ -272,7 +275,7 @@ fn join_orders_after_tls_destructors() {
272
275
273
276
impl Drop for TlDrop {
274
277
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 ) ;
276
279
loop {
277
280
match sync_state {
278
281
THREAD2_LAUNCHED | THREAD1_WAITING => thread:: yield_now ( ) ,
@@ -282,7 +285,7 @@ fn join_orders_after_tls_destructors() {
282
285
) ,
283
286
v => unreachable ! ( "sync state: {}" , v) ,
284
287
}
285
- sync_state = SYNC_STATE . load ( Ordering :: SeqCst ) ;
288
+ sync_state = SYNC_STATE . load ( Ordering :: Relaxed ) ;
286
289
}
287
290
}
288
291
}
@@ -294,7 +297,7 @@ fn join_orders_after_tls_destructors() {
294
297
TL_DROP . with ( |_| { } ) ;
295
298
296
299
loop {
297
- match SYNC_STATE . load ( Ordering :: SeqCst ) {
300
+ match SYNC_STATE . load ( Ordering :: Relaxed ) {
298
301
FRESH => thread:: yield_now ( ) ,
299
302
THREAD2_LAUNCHED => break ,
300
303
v => unreachable ! ( "sync state: {}" , v) ,
@@ -306,9 +309,9 @@ fn join_orders_after_tls_destructors() {
306
309
let jh2 = thread:: Builder :: new ( )
307
310
. name ( "thread2" . into ( ) )
308
311
. spawn ( move || {
309
- assert_eq ! ( SYNC_STATE . swap( THREAD2_LAUNCHED , Ordering :: SeqCst ) , FRESH ) ;
312
+ assert_eq ! ( SYNC_STATE . swap( THREAD2_LAUNCHED , Ordering :: Relaxed ) , FRESH ) ;
310
313
jh. join ( ) . unwrap ( ) ;
311
- match SYNC_STATE . swap ( THREAD2_JOINED , Ordering :: SeqCst ) {
314
+ match SYNC_STATE . swap ( THREAD2_JOINED , Ordering :: Relaxed ) {
312
315
MAIN_THREAD_RENDEZVOUS => return ,
313
316
THREAD2_LAUNCHED | THREAD1_WAITING => {
314
317
panic ! ( "Thread 2 running after thread 1 join before main thread rendezvous" )
@@ -322,8 +325,8 @@ fn join_orders_after_tls_destructors() {
322
325
match SYNC_STATE . compare_exchange (
323
326
THREAD1_WAITING ,
324
327
MAIN_THREAD_RENDEZVOUS ,
325
- Ordering :: SeqCst ,
326
- Ordering :: SeqCst ,
328
+ Ordering :: Relaxed ,
329
+ Ordering :: Relaxed ,
327
330
) {
328
331
Ok ( _) => break ,
329
332
Err ( FRESH ) => thread:: yield_now ( ) ,
0 commit comments