Skip to content

Commit acf696b

Browse files
committed
Move type definitions together and clarify fetch_store on empty buffer
1 parent 14684e6 commit acf696b

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

src/weak_memory.rs

+32-27
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,40 @@ use crate::{
4040

4141
pub type AllocExtra = StoreBufferAlloc;
4242

43+
const STORE_BUFFER_LIMIT: usize = 128;
44+
4345
#[derive(Debug, Clone)]
4446
pub struct StoreBufferAlloc {
4547
/// Store buffer of each atomic object in this allocation
4648
// Behind a RefCell because we need to allocate/remove on read access
4749
store_buffer: RefCell<AllocationMap<StoreBuffer>>,
4850
}
4951

52+
#[derive(Debug, Clone, PartialEq, Eq)]
53+
pub struct StoreBuffer {
54+
// Stores to this location in modification order
55+
buffer: VecDeque<StoreElement>,
56+
}
57+
58+
#[derive(Debug, Clone, PartialEq, Eq)]
59+
pub struct StoreElement {
60+
/// The identifier of the vector index, corresponding to a thread
61+
/// that performed the store.
62+
store_index: VectorIdx,
63+
64+
/// Whether this store is SC.
65+
is_seqcst: bool,
66+
67+
/// The timestamp of the storing thread when it performed the store
68+
timestamp: VTimestamp,
69+
/// The value of this store
70+
val: ScalarMaybeUninit<Tag>,
71+
72+
/// Timestamp of first loads from this store element by each thread
73+
/// Behind a RefCell to keep load op take &self
74+
loads: RefCell<FxHashMap<VectorIdx, VTimestamp>>,
75+
}
76+
5077
impl StoreBufferAlloc {
5178
pub fn new_allocation() -> Self {
5279
Self { store_buffer: RefCell::new(AllocationMap::new()) }
@@ -105,13 +132,6 @@ impl StoreBufferAlloc {
105132
}
106133
}
107134

108-
const STORE_BUFFER_LIMIT: usize = 128;
109-
#[derive(Debug, Clone, PartialEq, Eq)]
110-
pub struct StoreBuffer {
111-
// Stores to this location in modification order
112-
buffer: VecDeque<StoreElement>,
113-
}
114-
115135
impl Default for StoreBuffer {
116136
fn default() -> Self {
117137
let mut buffer = VecDeque::new();
@@ -175,7 +195,11 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
175195

176196
/// Selects a valid store element in the buffer.
177197
/// The buffer does not contain the value used to initialise the atomic object
178-
/// so a fresh atomic object has an empty store buffer until an explicit store.
198+
/// so a fresh atomic object has an empty store buffer and this function
199+
/// will return `None`. In this case, the caller should ensure that the non-buffered
200+
/// value from `MiriEvalContext::read_scalar()` is observed by the program, which is
201+
/// the initial value of the atomic object. `MiriEvalContext::read_scalar()` is always
202+
/// the latest value in modification order so it is always correct to be observed by any thread.
179203
fn fetch_store<R: rand::Rng + ?Sized>(
180204
&self,
181205
is_seqcst: bool,
@@ -294,25 +318,6 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
294318
}
295319
}
296320

297-
#[derive(Debug, Clone, PartialEq, Eq)]
298-
pub struct StoreElement {
299-
/// The identifier of the vector index, corresponding to a thread
300-
/// that performed the store.
301-
store_index: VectorIdx,
302-
303-
/// Whether this store is SC.
304-
is_seqcst: bool,
305-
306-
/// The timestamp of the storing thread when it performed the store
307-
timestamp: VTimestamp,
308-
/// The value of this store
309-
val: ScalarMaybeUninit<Tag>,
310-
311-
/// Timestamp of first loads from this store element by each thread
312-
/// Behind a RefCell to keep load op take &self
313-
loads: RefCell<FxHashMap<VectorIdx, VTimestamp>>,
314-
}
315-
316321
impl StoreElement {
317322
/// ATOMIC LOAD IMPL in the paper
318323
/// Unlike the operational semantics in the paper, we don't need to keep track

0 commit comments

Comments
 (0)