@@ -53,48 +53,63 @@ impl StoreBufferAlloc {
53
53
}
54
54
55
55
/// Gets a store buffer associated with an atomic object in this allocation
56
- fn get_store_buffer ( & self , range : AllocRange ) -> Ref < ' _ , StoreBuffer > {
56
+ pub fn get_store_buffer ( & self , range : AllocRange ) -> Ref < ' _ , StoreBuffer > {
57
57
Ref :: map ( self . store_buffer . borrow ( ) , |range_map| {
58
58
let ( .., store_buffer) = range_map. iter ( range. start , range. size ) . next ( ) . unwrap ( ) ;
59
59
store_buffer
60
60
} )
61
61
}
62
62
63
- fn get_store_buffer_mut ( & self , range : AllocRange ) -> RefMut < ' _ , StoreBuffer > {
63
+ pub fn get_store_buffer_mut ( & self , range : AllocRange ) -> RefMut < ' _ , StoreBuffer > {
64
64
RefMut :: map ( self . store_buffer . borrow_mut ( ) , |range_map| {
65
65
let ( .., store_buffer) = range_map. iter_mut ( range. start , range. size ) . next ( ) . unwrap ( ) ;
66
66
store_buffer
67
67
} )
68
68
}
69
69
70
+ }
71
+
72
+ const STORE_BUFFER_LIMIT : usize = 128 ;
73
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
74
+ pub struct StoreBuffer {
75
+ // Stores to this location in modification order
76
+ buffer : VecDeque < StoreElement > ,
77
+ }
78
+
79
+ impl Default for StoreBuffer {
80
+ fn default ( ) -> Self {
81
+ let mut buffer = VecDeque :: new ( ) ;
82
+ buffer. reserve ( STORE_BUFFER_LIMIT ) ;
83
+ Self { buffer }
84
+ }
85
+ }
86
+
87
+ impl < ' mir , ' tcx : ' mir > StoreBuffer {
70
88
/// Reads from the last store in modification order
71
- pub fn read_from_last_store < ' tcx > ( & self , range : AllocRange , global : & GlobalState ) {
72
- let store_buffer = self . get_store_buffer ( range) ;
73
- let store_elem = store_buffer. buffer . back ( ) ;
89
+ pub fn read_from_last_store ( & self , global : & GlobalState ) {
90
+ let store_elem = self . buffer . back ( ) ;
74
91
if let Some ( store_elem) = store_elem {
75
92
let ( index, clocks) = global. current_thread_state ( ) ;
76
93
store_elem. load_impl ( index, & clocks) ;
77
94
}
78
95
}
79
96
80
- pub fn buffered_read < ' tcx > (
97
+ pub fn buffered_read (
81
98
& self ,
82
- range : AllocRange ,
83
99
global : & GlobalState ,
84
100
is_seqcst : bool ,
85
101
rng : & mut ( impl rand:: Rng + ?Sized ) ,
86
102
validate : impl FnOnce ( ) -> InterpResult < ' tcx > ,
87
103
) -> InterpResult < ' tcx , Option < ScalarMaybeUninit < Tag > > > {
88
104
// Having a live borrow to store_buffer while calling validate_atomic_load is fine
89
105
// because the race detector doesn't touch store_buffer
90
- let store_buffer = self . get_store_buffer ( range) ;
91
106
92
107
let store_elem = {
93
108
// The `clocks` we got here must be dropped before calling validate_atomic_load
94
109
// as the race detector will update it
95
110
let ( .., clocks) = global. current_thread_state ( ) ;
96
111
// Load from a valid entry in the store buffer
97
- store_buffer . fetch_store ( is_seqcst, & clocks, & mut * rng)
112
+ self . fetch_store ( is_seqcst, & clocks, & mut * rng)
98
113
} ;
99
114
100
115
// Unlike in write_scalar_atomic, thread clock updates have to be done
@@ -110,37 +125,18 @@ impl StoreBufferAlloc {
110
125
Ok ( loaded)
111
126
}
112
127
113
- pub fn buffered_write < ' tcx > (
128
+ pub fn buffered_write (
114
129
& mut self ,
115
130
val : ScalarMaybeUninit < Tag > ,
116
- range : AllocRange ,
117
131
global : & GlobalState ,
118
132
is_seqcst : bool ,
119
133
) -> InterpResult < ' tcx > {
120
134
let ( index, clocks) = global. current_thread_state ( ) ;
121
135
122
- let mut store_buffer = self . get_store_buffer_mut ( range) ;
123
- store_buffer. store_impl ( val, index, & clocks. clock , is_seqcst) ;
136
+ self . store_impl ( val, index, & clocks. clock , is_seqcst) ;
124
137
Ok ( ( ) )
125
138
}
126
- }
127
139
128
- const STORE_BUFFER_LIMIT : usize = 128 ;
129
- #[ derive( Debug , Clone , PartialEq , Eq ) ]
130
- pub struct StoreBuffer {
131
- // Stores to this location in modification order
132
- buffer : VecDeque < StoreElement > ,
133
- }
134
-
135
- impl Default for StoreBuffer {
136
- fn default ( ) -> Self {
137
- let mut buffer = VecDeque :: new ( ) ;
138
- buffer. reserve ( STORE_BUFFER_LIMIT ) ;
139
- Self { buffer }
140
- }
141
- }
142
-
143
- impl < ' mir , ' tcx : ' mir > StoreBuffer {
144
140
/// Selects a valid store element in the buffer.
145
141
/// The buffer does not contain the value used to initialise the atomic object
146
142
/// so a fresh atomic object has an empty store buffer until an explicit store.
0 commit comments