Skip to content

Commit 2321b15

Browse files
committed
Differentiate between not multithreading and temp disabling race detection
1 parent 7dcb19e commit 2321b15

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

src/concurrency/data_race.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -445,14 +445,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
445445
#[inline]
446446
fn allow_data_races_ref<R>(&self, op: impl FnOnce(&MiriEvalContext<'mir, 'tcx>) -> R) -> R {
447447
let this = self.eval_context_ref();
448-
let old = if let Some(data_race) = &this.machine.data_race {
449-
data_race.multi_threaded.replace(false)
450-
} else {
451-
false
452-
};
448+
if let Some(data_race) = &this.machine.data_race {
449+
data_race.ongoing_atomic_access.set(true);
450+
}
453451
let result = op(this);
454452
if let Some(data_race) = &this.machine.data_race {
455-
data_race.multi_threaded.set(old);
453+
data_race.ongoing_atomic_access.set(false);
456454
}
457455
result
458456
}
@@ -466,14 +464,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
466464
op: impl FnOnce(&mut MiriEvalContext<'mir, 'tcx>) -> R,
467465
) -> R {
468466
let this = self.eval_context_mut();
469-
let old = if let Some(data_race) = &this.machine.data_race {
470-
data_race.multi_threaded.replace(false)
471-
} else {
472-
false
473-
};
467+
if let Some(data_race) = &this.machine.data_race {
468+
data_race.ongoing_atomic_access.set(true);
469+
}
474470
let result = op(this);
475471
if let Some(data_race) = &this.machine.data_race {
476-
data_race.multi_threaded.set(old);
472+
data_race.ongoing_atomic_access.set(false);
477473
}
478474
result
479475
}
@@ -923,7 +919,7 @@ impl VClockAlloc {
923919
}
924920

925921
/// Detect data-races for an unsynchronized read operation, will not perform
926-
/// data-race detection if `multi-threaded` is false, either due to no threads
922+
/// data-race detection if `race_detecting()` is false, either due to no threads
927923
/// being created or if it is temporarily disabled during a racy read or write
928924
/// operation for which data-race detection is handled separately, for example
929925
/// atomic read operations.
@@ -933,7 +929,7 @@ impl VClockAlloc {
933929
range: AllocRange,
934930
global: &GlobalState,
935931
) -> InterpResult<'tcx> {
936-
if global.multi_threaded.get() {
932+
if global.race_detecting() {
937933
let (index, clocks) = global.current_thread_state();
938934
let mut alloc_ranges = self.alloc_ranges.borrow_mut();
939935
for (offset, range) in alloc_ranges.iter_mut(range.start, range.size) {
@@ -962,7 +958,7 @@ impl VClockAlloc {
962958
write_type: WriteType,
963959
global: &mut GlobalState,
964960
) -> InterpResult<'tcx> {
965-
if global.multi_threaded.get() {
961+
if global.race_detecting() {
966962
let (index, clocks) = global.current_thread_state();
967963
for (offset, range) in self.alloc_ranges.get_mut().iter_mut(range.start, range.size) {
968964
if let Err(DataRace) = range.write_race_detect(&*clocks, index, write_type) {
@@ -983,7 +979,7 @@ impl VClockAlloc {
983979
}
984980

985981
/// Detect data-races for an unsynchronized write operation, will not perform
986-
/// data-race threads if `multi-threaded` is false, either due to no threads
982+
/// data-race threads if `race_detecting()` is false, either due to no threads
987983
/// being created or if it is temporarily disabled during a racy read or write
988984
/// operation
989985
pub fn write<'tcx>(
@@ -996,7 +992,7 @@ impl VClockAlloc {
996992
}
997993

998994
/// Detect data-races for an unsynchronized deallocate operation, will not perform
999-
/// data-race threads if `multi-threaded` is false, either due to no threads
995+
/// data-race threads if `race_detecting()` is false, either due to no threads
1000996
/// being created or if it is temporarily disabled during a racy read or write
1001997
/// operation
1002998
pub fn deallocate<'tcx>(
@@ -1026,7 +1022,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
10261022
) -> InterpResult<'tcx> {
10271023
let this = self.eval_context_ref();
10281024
if let Some(data_race) = &this.machine.data_race {
1029-
if data_race.multi_threaded.get() {
1025+
if data_race.race_detecting() {
10301026
let size = place.layout.size;
10311027
let (alloc_id, base_offset, _tag) = this.ptr_get_alloc_id(place.ptr)?;
10321028
// Load and log the atomic operation.
@@ -1116,6 +1112,10 @@ pub struct GlobalState {
11161112
/// any data-races.
11171113
multi_threaded: Cell<bool>,
11181114

1115+
/// A flag to mark we are currently performing
1116+
/// an atomic access to supress data race detection
1117+
ongoing_atomic_access: Cell<bool>,
1118+
11191119
/// Mapping of a vector index to a known set of thread
11201120
/// clocks, this is not directly mapping from a thread id
11211121
/// since it may refer to multiple threads.
@@ -1167,6 +1167,7 @@ impl GlobalState {
11671167
pub fn new() -> Self {
11681168
let mut global_state = GlobalState {
11691169
multi_threaded: Cell::new(false),
1170+
ongoing_atomic_access: Cell::new(false),
11701171
vector_clocks: RefCell::new(IndexVec::new()),
11711172
vector_info: RefCell::new(IndexVec::new()),
11721173
thread_info: RefCell::new(IndexVec::new()),
@@ -1192,6 +1193,13 @@ impl GlobalState {
11921193
global_state
11931194
}
11941195

1196+
// We perform data race detection when there are more than 1 active thread
1197+
// and we are not currently in the middle of an atomic acces where data race
1198+
// is impossible
1199+
fn race_detecting(&self) -> bool {
1200+
self.multi_threaded.get() && !self.ongoing_atomic_access.get()
1201+
}
1202+
11951203
// Try to find vector index values that can potentially be re-used
11961204
// by a new thread instead of a new vector index being created.
11971205
fn find_vector_index_reuse_candidate(&self) -> Option<VectorIdx> {

0 commit comments

Comments
 (0)