@@ -110,6 +110,16 @@ impl Default for StoreBuffer {
110
110
}
111
111
}
112
112
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)
113
123
impl < ' mir , ' tcx : ' mir > StoreBuffer {
114
124
/// Selects a valid store element in the buffer.
115
125
/// The buffer does not contain the value used to initialise the atomic object
@@ -134,7 +144,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
134
144
if !keep_searching {
135
145
return false ;
136
146
}
137
- // CoWR: if a store in modification order happens-before the current load,
147
+ // CoWR: if a store happens-before the current load,
138
148
// then we can't read-from anything earlier in modification order.
139
149
if store_elem. timestamp <= clocks. clock [ store_elem. store_index ] {
140
150
log:: info!( "Stopped due to coherent write-read" ) ;
@@ -196,9 +206,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
196
206
candidates. choose ( rng)
197
207
}
198
208
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)
202
210
fn store_impl (
203
211
& mut self ,
204
212
val : ScalarMaybeUninit < Tag > ,
@@ -223,12 +231,8 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
223
231
}
224
232
if is_seqcst {
225
233
// 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
227
235
// 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.
232
236
self . buffer . iter_mut ( ) . rev ( ) . for_each ( |elem| {
233
237
if elem. timestamp <= thread_clock[ elem. store_index ] {
234
238
elem. is_seqcst = true ;
0 commit comments