2
2
3
3
4
4
use std:: sync:: atomic:: { AtomicUsize , fence, Ordering } ;
5
- use std:: thread:: spawn;
5
+ use std:: thread:: { spawn, yield_now } ;
6
6
7
7
#[ derive( Copy , Clone ) ]
8
8
struct EvilSend < T > ( pub T ) ;
@@ -12,6 +12,21 @@ unsafe impl<T> Sync for EvilSend<T> {}
12
12
13
13
static SYNC : AtomicUsize = AtomicUsize :: new ( 0 ) ;
14
14
15
+ // Spins and yields until until acquires a pre-determined value
16
+ fn acquires_value ( loc : & AtomicUsize , val : usize ) -> usize {
17
+ while loc. load ( Ordering :: Acquire ) != val {
18
+ yield_now ( ) ;
19
+ }
20
+ val
21
+ }
22
+
23
+ fn reads_value ( loc : & AtomicUsize , val : usize ) -> usize {
24
+ while loc. load ( Ordering :: Relaxed ) != val {
25
+ yield_now ( ) ;
26
+ }
27
+ val
28
+ }
29
+
15
30
fn test_fence_sync ( ) {
16
31
let mut var = 0u32 ;
17
32
let ptr = & mut var as * mut u32 ;
@@ -25,12 +40,9 @@ fn test_fence_sync() {
25
40
} ) ;
26
41
27
42
let j2 = spawn ( move || {
28
- if SYNC . load ( Ordering :: Relaxed ) == 1 {
29
- fence ( Ordering :: Acquire ) ;
30
- unsafe { * evil_ptr. 0 }
31
- } else {
32
- 0
33
- }
43
+ reads_value ( & SYNC , 1 ) ;
44
+ fence ( Ordering :: Acquire ) ;
45
+ unsafe { * evil_ptr. 0 }
34
46
} ) ;
35
47
36
48
j1. join ( ) . unwrap ( ) ;
@@ -69,23 +81,20 @@ pub fn test_rmw_no_block() {
69
81
} ) ;
70
82
71
83
let j2 = spawn ( move || {
72
- if SYNC . swap ( 2 , Ordering :: Relaxed ) = = 1 {
84
+ while SYNC . swap ( 2 , Ordering :: Relaxed ) ! = 1 {
73
85
//No op, blocking store removed
74
86
}
75
87
} ) ;
76
88
77
89
let j3 = spawn ( move || {
78
- if SYNC . load ( Ordering :: Acquire ) == 2 {
79
- * c. 0
80
- } else {
81
- 0
82
- }
90
+ acquires_value ( & SYNC , 2 ) ;
91
+ * c. 0
83
92
} ) ;
84
93
85
94
j1. join ( ) . unwrap ( ) ;
86
95
j2. join ( ) . unwrap ( ) ;
87
96
let v = j3. join ( ) . unwrap ( ) ;
88
- assert ! ( v == 1 || v == 2 ) ;
97
+ assert ! ( v == 1 ) ;
89
98
}
90
99
}
91
100
@@ -101,11 +110,8 @@ pub fn test_simple_release() {
101
110
} ) ;
102
111
103
112
let j2 = spawn ( move || {
104
- if SYNC . load ( Ordering :: Acquire ) == 1 {
105
- * c. 0
106
- } else {
107
- 0
108
- }
113
+ acquires_value ( & SYNC , 1 ) ;
114
+ * c. 0
109
115
} ) ;
110
116
111
117
j1. join ( ) . unwrap ( ) ;
0 commit comments