miri

Struct ThreadManager

Source
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>

Source

pub(crate) fn init( ecx: &mut MiriInterpCx<'tcx>, on_main_stack_empty: StackEmptyCallback<'tcx>, )

Source

pub fn thread_id_try_from( &self, id: impl TryInto<u32>, ) -> Result<ThreadId, ThreadNotFound>

Source

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.

Source

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.

Source

pub fn active_thread_stack( &self, ) -> &[Frame<'tcx, Provenance, FrameExtra<'tcx>>]

Borrow the stack of the active thread.

Source

pub fn active_thread_stack_mut( &mut self, ) -> &mut Vec<Frame<'tcx, Provenance, FrameExtra<'tcx>>>

Mutably borrow the stack of the active thread.

Source

pub fn all_stacks( &self, ) -> impl Iterator<Item = (ThreadId, &[Frame<'tcx, Provenance, FrameExtra<'tcx>>])>

Source

fn create_thread( &mut self, on_stack_empty: StackEmptyCallback<'tcx>, ) -> ThreadId

Create a new thread and returns its id.

Source

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.

Source

pub fn active_thread(&self) -> ThreadId

Get the id of the currently active thread.

Source

pub fn get_total_thread_count(&self) -> usize

Get the total number of threads that were ever spawn by this program.

Source

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.)

Source

fn has_terminated(&self, thread_id: ThreadId) -> bool

Has the given thread terminated?

Source

fn have_all_terminated(&self) -> bool

Have all threads terminated?

Source

fn enable_thread(&mut self, thread_id: ThreadId)

Enable the thread for execution. The thread must be terminated.

Source

pub fn active_thread_mut(&mut self) -> &mut Thread<'tcx>

Get a mutable borrow of the currently active thread.

Source

pub fn active_thread_ref(&self) -> &Thread<'tcx>

Get a shared borrow of the currently active thread.

Source

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.

Source

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.

Source

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

Source

pub fn set_thread_name(&mut self, thread: ThreadId, new_thread_name: Vec<u8>)

Set the name of the given thread.

Source

pub fn get_thread_name(&self, thread: ThreadId) -> Option<&[u8]>

Get the name of the given thread.

Source

pub fn get_thread_display_name(&self, thread: ThreadId) -> String

Source

fn block_thread( &mut self, reason: BlockReason, timeout: Option<Timeout>, callback: Box<dyn UnblockCallback<'tcx> + 'tcx>, )

Put the thread into the blocked state.

Source

fn yield_active_thread(&mut self)

Change the active thread to some enabled thread.

Source

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.

Source

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>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'tcx> Default for ThreadManager<'tcx>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl VisitProvenance for ThreadManager<'_>

Source§

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

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