Skip to content

Commit a5622a2

Browse files
committed
fix SC fence logic
1 parent a57d5fe commit a5622a2

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

src/tools/miri/src/concurrency/data_race.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -874,23 +874,27 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
874874
// Either Acquire | AcqRel | SeqCst
875875
clocks.apply_acquire_fence();
876876
}
877-
if atomic != AtomicFenceOrd::Acquire {
878-
// Either Release | AcqRel | SeqCst
879-
clocks.apply_release_fence();
880-
}
881877
if atomic == AtomicFenceOrd::SeqCst {
882878
// Behave like an RMW on the global fence location. This takes full care of
883879
// all the SC fence requirements, including C++17 §32.4 [atomics.order]
884880
// paragraph 6 (which would limit what future reads can see). It also rules
885881
// out many legal behaviors, but we don't currently have a model that would
886882
// be more precise.
883+
// Also see the second bullet on page 10 of
884+
// <https://www.cs.tau.ac.il/~orilahav/papers/popl21_robustness.pdf>.
887885
let mut sc_fence_clock = data_race.last_sc_fence.borrow_mut();
888886
sc_fence_clock.join(&clocks.clock);
889887
clocks.clock.join(&sc_fence_clock);
890888
// Also establish some sort of order with the last SC write that happened, globally
891889
// (but this is only respected by future reads).
892890
clocks.write_seqcst.join(&data_race.last_sc_write_per_thread.borrow());
893891
}
892+
// The release fence is last, since both of the above could alter our clock,
893+
// which should be part of what is being released.
894+
if atomic != AtomicFenceOrd::Acquire {
895+
// Either Release | AcqRel | SeqCst
896+
clocks.apply_release_fence();
897+
}
894898

895899
// Increment timestamp in case of release semantics.
896900
interp_ok(atomic != AtomicFenceOrd::Acquire)

0 commit comments

Comments
 (0)