@@ -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)
113123impl < ' 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