File tree 2 files changed +37
-0
lines changed
tests/run-pass/concurrency
2 files changed +37
-0
lines changed Original file line number Diff line number Diff line change @@ -216,6 +216,20 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
216
216
if self . buffer . len ( ) > STORE_BUFFER_LIMIT {
217
217
self . buffer . pop_front ( ) ;
218
218
}
219
+ if is_seqcst {
220
+ // Every store that happens before this needs to be marked as SC
221
+ // so that in fetch_store, only the last SC store (i.e. this one) or stores that
222
+ // aren't ordered by hb with the last SC is picked.
223
+ //
224
+ // This is described in the paper (§4.5) and implemented in tsan11
225
+ // (https://github.com/ChrisLidbury/tsan11/blob/ecbd6b81e9b9454e01cba78eb9d88684168132c7/lib/tsan/rtl/tsan_relaxed.cc#L160-L167)
226
+ // but absent in the operational semantics.
227
+ self . buffer . iter_mut ( ) . rev ( ) . for_each ( |elem| {
228
+ if elem. timestamp <= thread_clock[ elem. store_index ] {
229
+ elem. is_seqcst = true ;
230
+ }
231
+ } )
232
+ }
219
233
}
220
234
}
221
235
Original file line number Diff line number Diff line change @@ -63,6 +63,28 @@ fn reads_value(loc: &AtomicUsize, val: usize) -> usize {
63
63
val
64
64
}
65
65
66
+ // https://plv.mpi-sws.org/scfix/paper.pdf
67
+ // Test case SB
68
+ fn test_sc_store_buffering ( ) {
69
+ let x = static_atomic ( 0 ) ;
70
+ let y = static_atomic ( 0 ) ;
71
+
72
+ let j1 = spawn ( move || {
73
+ x. store ( 1 , SeqCst ) ;
74
+ y. load ( SeqCst )
75
+ } ) ;
76
+
77
+ let j2 = spawn ( move || {
78
+ y. store ( 1 , SeqCst ) ;
79
+ x. load ( SeqCst )
80
+ } ) ;
81
+
82
+ let a = j1. join ( ) . unwrap ( ) ;
83
+ let b = j2. join ( ) . unwrap ( ) ;
84
+
85
+ assert_ne ! ( ( a, b) , ( 0 , 0 ) ) ;
86
+ }
87
+
66
88
// https://plv.mpi-sws.org/scfix/paper.pdf
67
89
// 2.2 Second Problem: SC Fences are Too Weak
68
90
fn test_rwc_syncs ( ) {
@@ -247,6 +269,7 @@ pub fn main() {
247
269
// prehaps each function should be its own test case so they
248
270
// can be run in parallel
249
271
for _ in 0 ..500 {
272
+ test_sc_store_buffering ( ) ;
250
273
test_mixed_access ( ) ;
251
274
test_load_buffering_acq_rel ( ) ;
252
275
test_message_passing ( ) ;
You can’t perform that action at this time.
0 commit comments