Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ec5c4ab

Browse files
committedJan 27, 2022
Fix SC Store buffering and add test case
1 parent cec4b3c commit ec5c4ab

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed
 

‎src/weak_memory.rs

+14
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,20 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
216216
if self.buffer.len() > STORE_BUFFER_LIMIT {
217217
self.buffer.pop_front();
218218
}
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+
}
219233
}
220234
}
221235

‎tests/run-pass/concurrency/weak_memory.rs

+23
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ fn reads_value(loc: &AtomicUsize, val: usize) -> usize {
6363
val
6464
}
6565

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+
6688
// https://plv.mpi-sws.org/scfix/paper.pdf
6789
// 2.2 Second Problem: SC Fences are Too Weak
6890
fn test_rwc_syncs() {
@@ -247,6 +269,7 @@ pub fn main() {
247269
// prehaps each function should be its own test case so they
248270
// can be run in parallel
249271
for _ in 0..500 {
272+
test_sc_store_buffering();
250273
test_mixed_access();
251274
test_load_buffering_acq_rel();
252275
test_message_passing();

0 commit comments

Comments
 (0)
Please sign in to comment.