@@ -598,7 +598,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
598
598
// of the time, based on `rate`.
599
599
let rate = this. memory . extra . cmpxchg_weak_failure_rate ;
600
600
let cmpxchg_success = eq. to_bool ( ) ?
601
- && ( !can_fail_spuriously || this. memory . extra . rng . borrow_mut ( ) . gen :: < f64 > ( ) < rate) ;
601
+ && ( !can_fail_spuriously || this. memory . extra . rng . get_mut ( ) . gen :: < f64 > ( ) < rate) ;
602
602
let res = Immediate :: ScalarPair (
603
603
old. to_scalar_or_uninit ( ) ,
604
604
Scalar :: from_bool ( cmpxchg_success) . into ( ) ,
@@ -647,7 +647,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
647
647
place : & MPlaceTy < ' tcx , Tag > ,
648
648
atomic : AtomicWriteOp ,
649
649
) -> InterpResult < ' tcx > {
650
- let this = self . eval_context_ref ( ) ;
650
+ let this = self . eval_context_mut ( ) ;
651
651
this. validate_atomic_op (
652
652
place,
653
653
atomic,
@@ -672,7 +672,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
672
672
use AtomicRwOp :: * ;
673
673
let acquire = matches ! ( atomic, Acquire | AcqRel | SeqCst ) ;
674
674
let release = matches ! ( atomic, Release | AcqRel | SeqCst ) ;
675
- let this = self . eval_context_ref ( ) ;
675
+ let this = self . eval_context_mut ( ) ;
676
676
this. validate_atomic_op ( place, atomic, "Atomic RMW" , move |memory, clocks, index, _| {
677
677
if acquire {
678
678
memory. load_acquire ( clocks, index) ?;
@@ -690,7 +690,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
690
690
/// Update the data-race detector for an atomic fence on the current thread.
691
691
fn validate_atomic_fence ( & mut self , atomic : AtomicFenceOp ) -> InterpResult < ' tcx > {
692
692
let this = self . eval_context_mut ( ) ;
693
- if let Some ( data_race) = & this. memory . extra . data_race {
693
+ if let Some ( data_race) = & mut this. memory . extra . data_race {
694
694
data_race. maybe_perform_sync_operation ( move |index, mut clocks| {
695
695
log:: trace!( "Atomic fence on {:?} with ordering {:?}" , index, atomic) ;
696
696
@@ -771,7 +771,7 @@ impl VClockAlloc {
771
771
}
772
772
773
773
fn reset_clocks ( & mut self , offset : Size , len : Size ) {
774
- let mut alloc_ranges = self . alloc_ranges . borrow_mut ( ) ;
774
+ let alloc_ranges = self . alloc_ranges . get_mut ( ) ;
775
775
for ( _, range) in alloc_ranges. iter_mut ( offset, len) {
776
776
// Reset the portion of the range
777
777
* range = MemoryCellClocks :: new ( 0 , VectorIdx :: MAX_INDEX ) ;
@@ -1025,6 +1025,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
1025
1025
if let Some ( data_race) = & this. memory . extra . data_race {
1026
1026
if data_race. multi_threaded . get ( ) {
1027
1027
// Load and log the atomic operation.
1028
+ // Note that atomic loads are possible even from read-only allocations, so `get_alloc_extra_mut` is not an option.
1028
1029
let place_ptr = place. ptr . assert_ptr ( ) ;
1029
1030
let size = place. layout . size ;
1030
1031
let alloc_meta =
@@ -1105,6 +1106,7 @@ struct ThreadExtraState {
1105
1106
/// Global data-race detection state, contains the currently
1106
1107
/// executing thread as well as the vector-clocks associated
1107
1108
/// with each of the threads.
1109
+ // FIXME: it is probably better to have one large RefCell, than to have so many small ones.
1108
1110
#[ derive( Debug , Clone ) ]
1109
1111
pub struct GlobalState {
1110
1112
/// Set to true once the first additional
@@ -1158,7 +1160,7 @@ impl GlobalState {
1158
1160
/// Create a new global state, setup with just thread-id=0
1159
1161
/// advanced to timestamp = 1.
1160
1162
pub fn new ( ) -> Self {
1161
- let global_state = GlobalState {
1163
+ let mut global_state = GlobalState {
1162
1164
multi_threaded : Cell :: new ( false ) ,
1163
1165
vector_clocks : RefCell :: new ( IndexVec :: new ( ) ) ,
1164
1166
vector_info : RefCell :: new ( IndexVec :: new ( ) ) ,
@@ -1172,9 +1174,9 @@ impl GlobalState {
1172
1174
// Setup the main-thread since it is not explicitly created:
1173
1175
// uses vector index and thread-id 0, also the rust runtime gives
1174
1176
// the main-thread a name of "main".
1175
- let index = global_state. vector_clocks . borrow_mut ( ) . push ( ThreadClockSet :: default ( ) ) ;
1176
- global_state. vector_info . borrow_mut ( ) . push ( ThreadId :: new ( 0 ) ) ;
1177
- global_state. thread_info . borrow_mut ( ) . push ( ThreadExtraState {
1177
+ let index = global_state. vector_clocks . get_mut ( ) . push ( ThreadClockSet :: default ( ) ) ;
1178
+ global_state. vector_info . get_mut ( ) . push ( ThreadId :: new ( 0 ) ) ;
1179
+ global_state. thread_info . get_mut ( ) . push ( ThreadExtraState {
1178
1180
vector_index : Some ( index) ,
1179
1181
thread_name : Some ( "main" . to_string ( ) . into_boxed_str ( ) ) ,
1180
1182
termination_vector_clock : None ,
@@ -1221,7 +1223,7 @@ impl GlobalState {
1221
1223
// Hook for thread creation, enabled multi-threaded execution and marks
1222
1224
// the current thread timestamp as happening-before the current thread.
1223
1225
#[ inline]
1224
- pub fn thread_created ( & self , thread : ThreadId ) {
1226
+ pub fn thread_created ( & mut self , thread : ThreadId ) {
1225
1227
let current_index = self . current_index ( ) ;
1226
1228
1227
1229
// Increment the number of active threads.
@@ -1241,12 +1243,12 @@ impl GlobalState {
1241
1243
let created_index = if let Some ( reuse_index) = self . find_vector_index_reuse_candidate ( ) {
1242
1244
// Now re-configure the re-use candidate, increment the clock
1243
1245
// for the new sync use of the vector.
1244
- let mut vector_clocks = self . vector_clocks . borrow_mut ( ) ;
1246
+ let vector_clocks = self . vector_clocks . get_mut ( ) ;
1245
1247
vector_clocks[ reuse_index] . increment_clock ( reuse_index) ;
1246
1248
1247
1249
// Locate the old thread the vector was associated with and update
1248
1250
// it to represent the new thread instead.
1249
- let mut vector_info = self . vector_info . borrow_mut ( ) ;
1251
+ let vector_info = self . vector_info . get_mut ( ) ;
1250
1252
let old_thread = vector_info[ reuse_index] ;
1251
1253
vector_info[ reuse_index] = thread;
1252
1254
@@ -1258,7 +1260,7 @@ impl GlobalState {
1258
1260
} else {
1259
1261
// No vector re-use candidates available, instead create
1260
1262
// a new vector index.
1261
- let mut vector_info = self . vector_info . borrow_mut ( ) ;
1263
+ let vector_info = self . vector_info . get_mut ( ) ;
1262
1264
vector_info. push ( thread)
1263
1265
} ;
1264
1266
@@ -1268,7 +1270,7 @@ impl GlobalState {
1268
1270
thread_info[ thread] . vector_index = Some ( created_index) ;
1269
1271
1270
1272
// Create a thread clock set if applicable.
1271
- let mut vector_clocks = self . vector_clocks . borrow_mut ( ) ;
1273
+ let vector_clocks = self . vector_clocks . get_mut ( ) ;
1272
1274
if created_index == vector_clocks. next_index ( ) {
1273
1275
vector_clocks. push ( ThreadClockSet :: default ( ) ) ;
1274
1276
}
@@ -1289,9 +1291,9 @@ impl GlobalState {
1289
1291
/// Hook on a thread join to update the implicit happens-before relation
1290
1292
/// between the joined thread and the current thread.
1291
1293
#[ inline]
1292
- pub fn thread_joined ( & self , current_thread : ThreadId , join_thread : ThreadId ) {
1293
- let mut clocks_vec = self . vector_clocks . borrow_mut ( ) ;
1294
- let thread_info = self . thread_info . borrow ( ) ;
1294
+ pub fn thread_joined ( & mut self , current_thread : ThreadId , join_thread : ThreadId ) {
1295
+ let clocks_vec = self . vector_clocks . get_mut ( ) ;
1296
+ let thread_info = self . thread_info . get_mut ( ) ;
1295
1297
1296
1298
// Load the vector clock of the current thread.
1297
1299
let current_index = thread_info[ current_thread]
@@ -1329,9 +1331,9 @@ impl GlobalState {
1329
1331
1330
1332
// If the thread is marked as terminated but not joined
1331
1333
// then move the thread to the re-use set.
1332
- let mut termination = self . terminated_threads . borrow_mut ( ) ;
1334
+ let termination = self . terminated_threads . get_mut ( ) ;
1333
1335
if let Some ( index) = termination. remove ( & join_thread) {
1334
- let mut reuse = self . reuse_candidates . borrow_mut ( ) ;
1336
+ let reuse = self . reuse_candidates . get_mut ( ) ;
1335
1337
reuse. insert ( index) ;
1336
1338
}
1337
1339
}
@@ -1344,28 +1346,28 @@ impl GlobalState {
1344
1346
/// This should be called strictly before any calls to
1345
1347
/// `thread_joined`.
1346
1348
#[ inline]
1347
- pub fn thread_terminated ( & self ) {
1349
+ pub fn thread_terminated ( & mut self ) {
1348
1350
let current_index = self . current_index ( ) ;
1349
1351
1350
1352
// Increment the clock to a unique termination timestamp.
1351
- let mut vector_clocks = self . vector_clocks . borrow_mut ( ) ;
1353
+ let vector_clocks = self . vector_clocks . get_mut ( ) ;
1352
1354
let current_clocks = & mut vector_clocks[ current_index] ;
1353
1355
current_clocks. increment_clock ( current_index) ;
1354
1356
1355
1357
// Load the current thread id for the executing vector.
1356
- let vector_info = self . vector_info . borrow ( ) ;
1358
+ let vector_info = self . vector_info . get_mut ( ) ;
1357
1359
let current_thread = vector_info[ current_index] ;
1358
1360
1359
1361
// Load the current thread metadata, and move to a terminated
1360
1362
// vector state. Setting up the vector clock all join operations
1361
1363
// will use.
1362
- let mut thread_info = self . thread_info . borrow_mut ( ) ;
1364
+ let thread_info = self . thread_info . get_mut ( ) ;
1363
1365
let current = & mut thread_info[ current_thread] ;
1364
1366
current. termination_vector_clock = Some ( current_clocks. clock . clone ( ) ) ;
1365
1367
1366
1368
// Add this thread as a candidate for re-use after a thread join
1367
1369
// occurs.
1368
- let mut termination = self . terminated_threads . borrow_mut ( ) ;
1370
+ let termination = self . terminated_threads . get_mut ( ) ;
1369
1371
termination. insert ( current_thread, current_index) ;
1370
1372
1371
1373
// Reduce the number of active threads, now that a thread has
@@ -1392,9 +1394,9 @@ impl GlobalState {
1392
1394
/// the thread name is used for improved diagnostics
1393
1395
/// during a data-race.
1394
1396
#[ inline]
1395
- pub fn thread_set_name ( & self , thread : ThreadId , name : String ) {
1397
+ pub fn thread_set_name ( & mut self , thread : ThreadId , name : String ) {
1396
1398
let name = name. into_boxed_str ( ) ;
1397
- let mut thread_info = self . thread_info . borrow_mut ( ) ;
1399
+ let thread_info = self . thread_info . get_mut ( ) ;
1398
1400
thread_info[ thread] . thread_name = Some ( name) ;
1399
1401
}
1400
1402
0 commit comments