pub struct ThreadManager<'tcx> {
active_thread: ThreadId,
threads: IndexVec<ThreadId, Thread<'tcx>>,
thread_local_allocs: FxHashMap<(DefId, ThreadId), StrictPointer>,
yield_active_thread: bool,
}
Expand description
A set of threads.
Fields§
§active_thread: ThreadId
Identifier of the currently active thread.
threads: IndexVec<ThreadId, Thread<'tcx>>
Threads used in the program.
Note that this vector also contains terminated threads.
thread_local_allocs: FxHashMap<(DefId, ThreadId), StrictPointer>
A mapping from a thread-local static to the thread specific allocation.
yield_active_thread: bool
A flag that indicates that we should change the active thread.
Implementations§
Source§impl<'tcx> ThreadManager<'tcx>
impl<'tcx> ThreadManager<'tcx>
pub(crate) fn init( ecx: &mut MiriInterpCx<'tcx>, on_main_stack_empty: StackEmptyCallback<'tcx>, )
pub fn thread_id_try_from( &self, id: impl TryInto<u32>, ) -> Result<ThreadId, ThreadNotFound>
Sourcefn get_thread_local_alloc_id(&self, def_id: DefId) -> Option<StrictPointer>
fn get_thread_local_alloc_id(&self, def_id: DefId) -> Option<StrictPointer>
Check if we have an allocation for the given thread local static for the active thread.
Sourcefn set_thread_local_alloc(&mut self, def_id: DefId, ptr: StrictPointer)
fn set_thread_local_alloc(&mut self, def_id: DefId, ptr: StrictPointer)
Set the pointer for the allocation of the given thread local static for the active thread.
Panics if a thread local is initialized twice for the same thread.
Sourcepub fn active_thread_stack(
&self,
) -> &[Frame<'tcx, Provenance, FrameExtra<'tcx>>]
pub fn active_thread_stack( &self, ) -> &[Frame<'tcx, Provenance, FrameExtra<'tcx>>]
Borrow the stack of the active thread.
Sourcepub fn active_thread_stack_mut(
&mut self,
) -> &mut Vec<Frame<'tcx, Provenance, FrameExtra<'tcx>>>
pub fn active_thread_stack_mut( &mut self, ) -> &mut Vec<Frame<'tcx, Provenance, FrameExtra<'tcx>>>
Mutably borrow the stack of the active thread.
pub fn all_stacks( &self, ) -> impl Iterator<Item = (ThreadId, &[Frame<'tcx, Provenance, FrameExtra<'tcx>>])>
Sourcefn create_thread(
&mut self,
on_stack_empty: StackEmptyCallback<'tcx>,
) -> ThreadId
fn create_thread( &mut self, on_stack_empty: StackEmptyCallback<'tcx>, ) -> ThreadId
Create a new thread and returns its id.
Sourcefn set_active_thread_id(&mut self, id: ThreadId) -> ThreadId
fn set_active_thread_id(&mut self, id: ThreadId) -> ThreadId
Set an active thread and return the id of the thread that was active before.
Sourcepub fn active_thread(&self) -> ThreadId
pub fn active_thread(&self) -> ThreadId
Get the id of the currently active thread.
Sourcepub fn get_total_thread_count(&self) -> usize
pub fn get_total_thread_count(&self) -> usize
Get the total number of threads that were ever spawn by this program.
Sourcepub fn get_live_thread_count(&self) -> usize
pub fn get_live_thread_count(&self) -> usize
Get the total of threads that are currently live, i.e., not yet terminated. (They might be blocked.)
Sourcefn has_terminated(&self, thread_id: ThreadId) -> bool
fn has_terminated(&self, thread_id: ThreadId) -> bool
Has the given thread terminated?
Sourcefn have_all_terminated(&self) -> bool
fn have_all_terminated(&self) -> bool
Have all threads terminated?
Sourcefn enable_thread(&mut self, thread_id: ThreadId)
fn enable_thread(&mut self, thread_id: ThreadId)
Enable the thread for execution. The thread must be terminated.
Sourcepub fn active_thread_mut(&mut self) -> &mut Thread<'tcx>
pub fn active_thread_mut(&mut self) -> &mut Thread<'tcx>
Get a mutable borrow of the currently active thread.
Sourcepub fn active_thread_ref(&self) -> &Thread<'tcx>
pub fn active_thread_ref(&self) -> &Thread<'tcx>
Get a shared borrow of the currently active thread.
Sourcefn detach_thread(
&mut self,
id: ThreadId,
allow_terminated_joined: bool,
) -> InterpResult<'tcx>
fn detach_thread( &mut self, id: ThreadId, allow_terminated_joined: bool, ) -> InterpResult<'tcx>
Mark the thread as detached, which means that no other thread will try to join it and the thread is responsible for cleaning up.
allow_terminated_joined
allows detaching joined threads that have already terminated.
This matches Windows’s behavior for CloseHandle
.
See https://docs.microsoft.com/en-us/windows/win32/procthread/thread-handles-and-identifiers:
The handle is valid until closed, even after the thread it represents has been terminated.
Sourcefn join_thread(
&mut self,
joined_thread_id: ThreadId,
data_race: Option<&mut GlobalState>,
) -> InterpResult<'tcx>
fn join_thread( &mut self, joined_thread_id: ThreadId, data_race: Option<&mut GlobalState>, ) -> InterpResult<'tcx>
Mark that the active thread tries to join the thread with joined_thread_id
.
Sourcefn join_thread_exclusive(
&mut self,
joined_thread_id: ThreadId,
data_race: Option<&mut GlobalState>,
) -> InterpResult<'tcx>
fn join_thread_exclusive( &mut self, joined_thread_id: ThreadId, data_race: Option<&mut GlobalState>, ) -> InterpResult<'tcx>
Mark that the active thread tries to exclusively join the thread with joined_thread_id
.
If the thread is already joined by another thread, it will throw UB
Sourcepub fn set_thread_name(&mut self, thread: ThreadId, new_thread_name: Vec<u8>)
pub fn set_thread_name(&mut self, thread: ThreadId, new_thread_name: Vec<u8>)
Set the name of the given thread.
Sourcepub fn get_thread_name(&self, thread: ThreadId) -> Option<&[u8]>
pub fn get_thread_name(&self, thread: ThreadId) -> Option<&[u8]>
Get the name of the given thread.
pub fn get_thread_display_name(&self, thread: ThreadId) -> String
Sourcefn block_thread(
&mut self,
reason: BlockReason,
timeout: Option<Timeout>,
callback: Box<dyn UnblockCallback<'tcx> + 'tcx>,
)
fn block_thread( &mut self, reason: BlockReason, timeout: Option<Timeout>, callback: Box<dyn UnblockCallback<'tcx> + 'tcx>, )
Put the thread into the blocked state.
Sourcefn yield_active_thread(&mut self)
fn yield_active_thread(&mut self)
Change the active thread to some enabled thread.
Sourcefn next_callback_wait_time(&self, clock: &Clock) -> Option<Duration>
fn next_callback_wait_time(&self, clock: &Clock) -> Option<Duration>
Get the wait time for the next timeout, or None
if no timeout is pending.
Sourcefn schedule(&mut self, clock: &Clock) -> InterpResult<'tcx, SchedulingAction>
fn schedule(&mut self, clock: &Clock) -> InterpResult<'tcx, SchedulingAction>
Decide which action to take next and on which thread.
The currently implemented scheduling policy is the one that is commonly used in stateless model checkers such as Loom: run the active thread as long as we can and switch only when we have to (the active thread was blocked, terminated, or has explicitly asked to be preempted).
Trait Implementations§
Source§impl<'tcx> Debug for ThreadManager<'tcx>
impl<'tcx> Debug for ThreadManager<'tcx>
Source§impl<'tcx> Default for ThreadManager<'tcx>
impl<'tcx> Default for ThreadManager<'tcx>
Source§impl VisitProvenance for ThreadManager<'_>
impl VisitProvenance for ThreadManager<'_>
fn visit_provenance(&self, visit: &mut VisitWith<'_>)
Auto Trait Implementations§
impl<'tcx> Freeze for ThreadManager<'tcx>
impl<'tcx> !RefUnwindSafe for ThreadManager<'tcx>
impl<'tcx> !Send for ThreadManager<'tcx>
impl<'tcx> !Sync for ThreadManager<'tcx>
impl<'tcx> Unpin for ThreadManager<'tcx>
impl<'tcx> !UnwindSafe for ThreadManager<'tcx>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 64 bytes