global allocations: don't make up a super-high VectorIdx, just use the main thread

This commit is contained in:
Ralf Jung 2024-04-20 11:18:50 +02:00
parent 6b0ce8b1e2
commit 465dcf1320
3 changed files with 21 additions and 19 deletions

View File

@ -847,6 +847,7 @@ impl VClockAlloc {
kind: MemoryKind,
current_span: Span,
) -> VClockAlloc {
// Determine the thread that did the allocation, and when it did it.
let (alloc_timestamp, alloc_index) = match kind {
// User allocated and stack memory should track allocation.
MemoryKind::Machine(
@ -864,7 +865,7 @@ impl VClockAlloc {
(alloc_timestamp, alloc_index)
}
// Other global memory should trace races but be allocated at the 0 timestamp
// (conceptually they are allocated before everything).
// (conceptually they are allocated on the main thread before everything).
MemoryKind::Machine(
MiriMemoryKind::Global
| MiriMemoryKind::Machine
@ -872,7 +873,8 @@ impl VClockAlloc {
| MiriMemoryKind::ExternStatic
| MiriMemoryKind::Tls,
)
| MemoryKind::CallerLocation => (VTimestamp::ZERO, VectorIdx::MAX_INDEX),
| MemoryKind::CallerLocation =>
(VTimestamp::ZERO, global.thread_index(ThreadId::MAIN_THREAD)),
};
VClockAlloc {
alloc_ranges: RefCell::new(RangeMap::new(
@ -1454,7 +1456,7 @@ impl GlobalState {
// Setup the main-thread since it is not explicitly created:
// uses vector index and thread-id 0.
let index = global_state.vector_clocks.get_mut().push(ThreadClockSet::default());
global_state.vector_info.get_mut().push(ThreadId::new(0));
global_state.vector_info.get_mut().push(ThreadId::MAIN_THREAD);
global_state
.thread_info
.get_mut()
@ -1725,13 +1727,15 @@ impl GlobalState {
Ref::map(clocks, |c| &c.clock)
}
fn thread_index(&self, thread: ThreadId) -> VectorIdx {
self.thread_info.borrow()[thread].vector_index.expect("thread has no assigned vector")
}
/// Load the vector index used by the given thread as well as the set of vector clocks
/// used by the thread.
#[inline]
fn thread_state_mut(&self, thread: ThreadId) -> (VectorIdx, RefMut<'_, ThreadClockSet>) {
let index = self.thread_info.borrow()[thread]
.vector_index
.expect("Loading thread state for thread with no assigned vector");
let index = self.thread_index(thread);
let ref_vector = self.vector_clocks.borrow_mut();
let clocks = RefMut::map(ref_vector, |vec| &mut vec[index]);
(index, clocks)
@ -1741,9 +1745,7 @@ impl GlobalState {
/// used by the thread.
#[inline]
fn thread_state(&self, thread: ThreadId) -> (VectorIdx, Ref<'_, ThreadClockSet>) {
let index = self.thread_info.borrow()[thread]
.vector_index
.expect("Loading thread state for thread with no assigned vector");
let index = self.thread_index(thread);
let ref_vector = self.vector_clocks.borrow();
let clocks = Ref::map(ref_vector, |vec| &vec[index]);
(index, clocks)
@ -1774,9 +1776,7 @@ impl GlobalState {
#[inline]
fn current_index(&self, thread_mgr: &ThreadManager<'_, '_>) -> VectorIdx {
let active_thread_id = thread_mgr.get_active_thread_id();
self.thread_info.borrow()[active_thread_id]
.vector_index
.expect("active thread has no assigned vector")
self.thread_index(active_thread_id)
}
// SC ATOMIC STORE rule in the paper.

View File

@ -57,6 +57,8 @@ impl ThreadId {
pub fn to_u32(self) -> u32 {
self.0
}
pub const MAIN_THREAD: ThreadId = ThreadId(0);
}
impl Idx for ThreadId {
@ -401,7 +403,7 @@ impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> {
// Create the main thread and add it to the list of threads.
threads.push(Thread::new(Some("main"), None));
Self {
active_thread: ThreadId::new(0),
active_thread: ThreadId::MAIN_THREAD,
threads,
sync: SynchronizationState::default(),
thread_local_alloc_ids: Default::default(),
@ -416,10 +418,12 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
ecx: &mut MiriInterpCx<'mir, 'tcx>,
on_main_stack_empty: StackEmptyCallback<'mir, 'tcx>,
) {
ecx.machine.threads.threads[ThreadId::new(0)].on_stack_empty = Some(on_main_stack_empty);
ecx.machine.threads.threads[ThreadId::MAIN_THREAD].on_stack_empty =
Some(on_main_stack_empty);
if ecx.tcx.sess.target.os.as_ref() != "windows" {
// The main thread can *not* be joined on except on windows.
ecx.machine.threads.threads[ThreadId::new(0)].join_status = ThreadJoinStatus::Detached;
ecx.machine.threads.threads[ThreadId::MAIN_THREAD].join_status =
ThreadJoinStatus::Detached;
}
}

View File

@ -13,15 +13,13 @@ use super::data_race::NaReadType;
/// but in some cases one vector index may be shared with
/// multiple thread ids if it's safe to do so.
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct VectorIdx(u32);
pub(super) struct VectorIdx(u32);
impl VectorIdx {
#[inline(always)]
pub fn to_u32(self) -> u32 {
fn to_u32(self) -> u32 {
self.0
}
pub const MAX_INDEX: VectorIdx = VectorIdx(u32::MAX);
}
impl Idx for VectorIdx {