This commit is contained in:
Ralf Jung 2021-05-22 14:55:33 +02:00
parent 1bbd6e609c
commit c73f8b1097
4 changed files with 53 additions and 28 deletions

View file

@ -883,21 +883,19 @@ impl VClockAlloc {
/// being created or if it is temporarily disabled during a racy read or write
/// operation for which data-race detection is handled separately, for example
/// atomic read operations.
pub fn read<'tcx>(&self, pointer: Pointer<Tag>, len: Size, global: &GlobalState) -> InterpResult<'tcx> {
pub fn read<'tcx>(
&self,
pointer: Pointer<Tag>,
len: Size,
global: &GlobalState,
) -> InterpResult<'tcx> {
if global.multi_threaded.get() {
let (index, clocks) = global.current_thread_state();
let mut alloc_ranges = self.alloc_ranges.borrow_mut();
for (_, range) in alloc_ranges.iter_mut(pointer.offset, len) {
if let Err(DataRace) = range.read_race_detect(&*clocks, index) {
// Report data-race.
return Self::report_data_race(
global,
range,
"Read",
false,
pointer,
len,
);
return Self::report_data_race(global, range, "Read", false, pointer, len);
}
}
Ok(())
@ -939,7 +937,12 @@ impl VClockAlloc {
/// data-race threads if `multi-threaded` is false, either due to no threads
/// being created or if it is temporarily disabled during a racy read or write
/// operation
pub fn write<'tcx>(&mut self, pointer: Pointer<Tag>, len: Size, global: &mut GlobalState) -> InterpResult<'tcx> {
pub fn write<'tcx>(
&mut self,
pointer: Pointer<Tag>,
len: Size,
global: &mut GlobalState,
) -> InterpResult<'tcx> {
self.unique_access(pointer, len, WriteType::Write, global)
}
@ -947,7 +950,12 @@ impl VClockAlloc {
/// data-race threads if `multi-threaded` is false, either due to no threads
/// being created or if it is temporarily disabled during a racy read or write
/// operation
pub fn deallocate<'tcx>(&mut self, pointer: Pointer<Tag>, len: Size, global: &mut GlobalState) -> InterpResult<'tcx> {
pub fn deallocate<'tcx>(
&mut self,
pointer: Pointer<Tag>,
len: Size,
global: &mut GlobalState,
) -> InterpResult<'tcx> {
self.unique_access(pointer, len, WriteType::Deallocate, global)
}
}

View file

@ -151,11 +151,8 @@ impl MemoryExtra {
} else {
None
};
let data_race = if config.data_race_detector {
Some(data_race::GlobalState::new())
} else {
None
};
let data_race =
if config.data_race_detector { Some(data_race::GlobalState::new()) } else { None };
MemoryExtra {
stacked_borrows,
data_race,
@ -532,7 +529,11 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
data_race.write(ptr, size, memory_extra.data_race.as_mut().unwrap())?;
}
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
stacked_borrows.memory_written(ptr, size, memory_extra.stacked_borrows.as_mut().unwrap())
stacked_borrows.memory_written(
ptr,
size,
memory_extra.stacked_borrows.as_mut().unwrap(),
)
} else {
Ok(())
}
@ -552,7 +553,11 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
data_race.deallocate(ptr, size, memory_extra.data_race.as_mut().unwrap())?;
}
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
stacked_borrows.memory_deallocated(ptr, size, memory_extra.stacked_borrows.as_mut().unwrap())
stacked_borrows.memory_deallocated(
ptr,
size,
memory_extra.stacked_borrows.as_mut().unwrap(),
)
} else {
Ok(())
}

View file

@ -1,10 +1,10 @@
//! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md>
//! for further information.
use log::trace;
use std::cell::RefCell;
use std::fmt;
use std::num::NonZeroU64;
use log::trace;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::Mutability;
@ -509,15 +509,29 @@ impl Stacks {
}
#[inline(always)]
pub fn memory_read<'tcx>(&self, ptr: Pointer<Tag>, size: Size, extra: &MemoryExtra) -> InterpResult<'tcx> {
pub fn memory_read<'tcx>(
&self,
ptr: Pointer<Tag>,
size: Size,
extra: &MemoryExtra,
) -> InterpResult<'tcx> {
trace!("read access with tag {:?}: {:?}, size {}", ptr.tag, ptr.erase_tag(), size.bytes());
self.for_each(ptr, size, &*extra.borrow(), |ptr, stack, global| stack.access(AccessKind::Read, ptr, global))
self.for_each(ptr, size, &*extra.borrow(), |ptr, stack, global| {
stack.access(AccessKind::Read, ptr, global)
})
}
#[inline(always)]
pub fn memory_written<'tcx>(&mut self, ptr: Pointer<Tag>, size: Size, extra: &mut MemoryExtra) -> InterpResult<'tcx> {
pub fn memory_written<'tcx>(
&mut self,
ptr: Pointer<Tag>,
size: Size,
extra: &mut MemoryExtra,
) -> InterpResult<'tcx> {
trace!("write access with tag {:?}: {:?}, size {}", ptr.tag, ptr.erase_tag(), size.bytes());
self.for_each(ptr, size, extra.get_mut(), |ptr, stack, global| stack.access(AccessKind::Write, ptr, global))
self.for_each(ptr, size, extra.get_mut(), |ptr, stack, global| {
stack.access(AccessKind::Write, ptr, global)
})
}
#[inline(always)]
@ -589,7 +603,8 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
};
let item = Item { perm, tag: new_tag, protector };
stacked_borrows.for_each(ptr, size, &*global, |ptr, stack, global| stack.grant(ptr, item, global))
stacked_borrows
.for_each(ptr, size, &*global, |ptr, stack, global| stack.grant(ptr, item, global))
}
/// Retags an indidual pointer, returning the retagged version.

View file

@ -436,10 +436,7 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
/// Wakes up threads joining on the active one and deallocates thread-local statics.
/// The `AllocId` that can now be freed is returned.
fn thread_terminated(
&mut self,
data_race: &Option<data_race::GlobalState>,
) -> Vec<AllocId> {
fn thread_terminated(&mut self, data_race: &Option<data_race::GlobalState>) -> Vec<AllocId> {
let mut free_tls_statics = Vec::new();
{
let mut thread_local_statics = self.thread_local_alloc_ids.borrow_mut();