Skip to content

Commit 1b73d67

Browse files
committed
Comments addressing deviations from paper's operational semantics
1 parent dbde843 commit 1b73d67

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

src/weak_memory.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,16 @@ impl Default for StoreBuffer {
110110
}
111111
}
112112

113+
// Operational semantics in the paper has several problems:
114+
// 1. Store elements keep a copy of the atomic object's vector clock (AtomicCellClocks::sync_vector in miri),
115+
// but this is not used anywhere so it's omitted
116+
// 2. §4.5 of the paper wants an SC store to mark all existing stores in the buffer that happens before it
117+
// as SC. This is not done in the operational semantics but implemented correctly in tsan11
118+
// (https://github.com/ChrisLidbury/tsan11/blob/ecbd6b81e9b9454e01cba78eb9d88684168132c7/lib/tsan/rtl/tsan_relaxed.cc#L160-L167)
119+
// 3. W_SC ; R_SC case requires the SC load to ignore all but last store maked SC (stores not marked SC are not
120+
// affected). But this rule is applied to all loads in ReadsFromSet (last two lines of code), not just SC load.
121+
// This is implemented correctly in tsan11
122+
// (https://github.com/ChrisLidbury/tsan11/blob/ecbd6b81e9b9454e01cba78eb9d88684168132c7/lib/tsan/rtl/tsan_relaxed.cc#L295)
113123
impl<'mir, 'tcx: 'mir> StoreBuffer {
114124
/// Selects a valid store element in the buffer.
115125
/// The buffer does not contain the value used to initialise the atomic object
@@ -134,7 +144,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
134144
if !keep_searching {
135145
return false;
136146
}
137-
// CoWR: if a store in modification order happens-before the current load,
147+
// CoWR: if a store happens-before the current load,
138148
// then we can't read-from anything earlier in modification order.
139149
if store_elem.timestamp <= clocks.clock[store_elem.store_index] {
140150
log::info!("Stopped due to coherent write-read");
@@ -196,9 +206,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
196206
candidates.choose(rng)
197207
}
198208

199-
/// ATOMIC STORE IMPL in the paper
200-
/// The paper also wants the variable's clock (AtomicMemoryCellClocks::sync_vector in our code)
201-
/// to be in the store element, but it's not used anywhere so we don't actually need it
209+
/// ATOMIC STORE IMPL in the paper (except we don't need the location's vector clock)
202210
fn store_impl(
203211
&mut self,
204212
val: ScalarMaybeUninit<Tag>,
@@ -223,12 +231,8 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
223231
}
224232
if is_seqcst {
225233
// Every store that happens before this needs to be marked as SC
226-
// so that in fetch_store, only the last SC store (i.e. this one) or stores that
234+
// so that in a later SC load, only the last SC store (i.e. this one) or stores that
227235
// aren't ordered by hb with the last SC is picked.
228-
//
229-
// This is described in the paper (§4.5) and implemented in tsan11
230-
// (https://github.com/ChrisLidbury/tsan11/blob/ecbd6b81e9b9454e01cba78eb9d88684168132c7/lib/tsan/rtl/tsan_relaxed.cc#L160-L167)
231-
// but absent in the operational semantics.
232236
self.buffer.iter_mut().rev().for_each(|elem| {
233237
if elem.timestamp <= thread_clock[elem.store_index] {
234238
elem.is_seqcst = true;

0 commit comments

Comments
 (0)