pub struct GlobalState {
    multi_threaded: Cell<bool>,
    ongoing_action_data_race_free: Cell<bool>,
    vector_clocks: RefCell<IndexVec<VectorIdx, ThreadClockSet>>,
    vector_info: RefCell<IndexVec<VectorIdx, ThreadId>>,
    thread_info: RefCell<IndexVec<ThreadId, ThreadExtraState>>,
    reuse_candidates: RefCell<FxHashSet<VectorIdx>>,
    terminated_threads: RefCell<FxHashMap<ThreadId, VectorIdx>>,
    last_sc_fence: RefCell<VClock>,
    last_sc_write: RefCell<VClock>,
    pub track_outdated_loads: bool,
}
Expand description

Global data-race detection state, contains the currently executing thread as well as the vector-clocks associated with each of the threads.

Fields§

§multi_threaded: Cell<bool>

Set to true once the first additional thread has launched, due to the dependency between before and after a thread launch. Any data-races must be recorded after this so concurrent execution can ignore recording any data-races.

§ongoing_action_data_race_free: Cell<bool>

A flag to mark we are currently performing a data race free action (such as atomic access) to suppress the race detector

§vector_clocks: RefCell<IndexVec<VectorIdx, ThreadClockSet>>

Mapping of a vector index to a known set of thread clocks, this is not directly mapping from a thread id since it may refer to multiple threads.

§vector_info: RefCell<IndexVec<VectorIdx, ThreadId>>

Mapping of a given vector index to the current thread that the execution is representing, this may change if a vector index is re-assigned to a new thread.

§thread_info: RefCell<IndexVec<ThreadId, ThreadExtraState>>

The mapping of a given thread to associated thread metadata.

§reuse_candidates: RefCell<FxHashSet<VectorIdx>>

Potential vector indices that could be re-used on thread creation values are inserted here on after the thread has terminated and been joined with, and hence may potentially become free for use as the index for a new thread. Elements in this set may still require the vector index to report data-races, and can only be re-used after all active vector-clocks catch up with the threads timestamp.

§terminated_threads: RefCell<FxHashMap<ThreadId, VectorIdx>>

This contains threads that have terminated, but not yet joined and so cannot become re-use candidates until a join operation occurs. The associated vector index will be moved into re-use candidates after the join operation occurs.

§last_sc_fence: RefCell<VClock>

The timestamp of last SC fence performed by each thread

§last_sc_write: RefCell<VClock>

The timestamp of last SC write performed by each thread

§track_outdated_loads: bool

Track when an outdated (weak memory) load happens.

Implementations§

source§

impl GlobalState

source

pub fn new(config: &MiriConfig) -> Self

Create a new global state, setup with just thread-id=0 advanced to timestamp = 1.

source

fn race_detecting(&self) -> bool

source

pub fn ongoing_action_data_race_free(&self) -> bool

source

fn find_vector_index_reuse_candidate(&self) -> Option<VectorIdx>

source

pub fn thread_created( &mut self, thread_mgr: &ThreadManager<'_, '_>, thread: ThreadId, current_span: Span )

source

pub fn thread_joined( &mut self, thread_mgr: &ThreadManager<'_, '_>, joiner: ThreadId, joinee: ThreadId )

Hook on a thread join to update the implicit happens-before relation between the joined thread (the joinee, the thread that someone waited on) and the current thread (the joiner, the thread who was waiting).

source

pub fn thread_terminated( &mut self, thread_mgr: &ThreadManager<'_, '_>, current_span: Span )

On thread termination, the vector-clock may re-used in the future once all remaining thread-clocks catch up with the time index of the terminated thread. This assigns thread termination with a unique index which will be used to join the thread This should be called strictly before any calls to thread_joined.

source

fn maybe_perform_sync_operation<'tcx>( &self, thread_mgr: &ThreadManager<'_, '_>, current_span: Span, op: impl FnOnce(VectorIdx, RefMut<'_, ThreadClockSet>) -> InterpResult<'tcx, bool> ) -> InterpResult<'tcx>

Attempt to perform a synchronized operation, this will perform no operation if multi-threading is not currently enabled. Otherwise it will increment the clock for the current vector before and after the operation for data-race detection between any happens-before edges the operation may create.

source

fn print_thread_metadata( &self, thread_mgr: &ThreadManager<'_, '_>, vector: VectorIdx ) -> String

Internal utility to identify a thread stored internally returns the id and the name for better diagnostics.

source

pub fn validate_lock_acquire(&self, lock: &VClock, thread: ThreadId)

Acquire a lock, express that the previous call of validate_lock_release must happen before this. As this is an acquire operation, the thread timestamp is not incremented.

source

pub fn validate_lock_release( &self, lock: &mut VClock, thread: ThreadId, current_span: Span )

Release a lock handle, express that this happens-before any subsequent calls to validate_lock_acquire. For normal locks this should be equivalent to validate_lock_release_shared since an acquire operation should have occurred before, however for futex & condvar operations this is not the case and this operation must be used.

source

pub fn validate_lock_release_shared( &self, lock: &mut VClock, thread: ThreadId, current_span: Span )

Release a lock handle, express that this happens-before any subsequent calls to validate_lock_acquire as well as any previous calls to this function after any validate_lock_release calls. For normal locks this should be equivalent to validate_lock_release. This function only exists for joining over the set of concurrent readers in a read-write lock and should not be used for anything else.

source

fn load_thread_state_mut( &self, thread: ThreadId ) -> (VectorIdx, RefMut<'_, ThreadClockSet>)

Load the vector index used by the given thread as well as the set of vector clocks used by the thread.

source

pub(super) fn current_thread_state( &self, thread_mgr: &ThreadManager<'_, '_> ) -> (VectorIdx, Ref<'_, ThreadClockSet>)

Load the current vector clock in use and the current set of thread clocks in use for the vector.

source

pub(super) fn current_thread_state_mut( &self, thread_mgr: &ThreadManager<'_, '_> ) -> (VectorIdx, RefMut<'_, ThreadClockSet>)

Load the current vector clock in use and the current set of thread clocks in use for the vector mutably for modification.

source

fn current_index(&self, thread_mgr: &ThreadManager<'_, '_>) -> VectorIdx

Return the current thread, should be the same as the data-race active thread.

source

pub(super) fn sc_write(&self, thread_mgr: &ThreadManager<'_, '_>)

source

pub(super) fn sc_read(&self, thread_mgr: &ThreadManager<'_, '_>)

Trait Implementations§

source§

impl Clone for GlobalState

source§

fn clone(&self) -> GlobalState

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for GlobalState

source§

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

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

impl VisitProvenance for GlobalState

source§

fn visit_provenance(&self, _visit: &mut VisitWith<'_>)

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Aligned for T

source§

const ALIGN: Alignment = _

Alignment of Self.
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, R> CollectAndApply<T, R> for T

source§

fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to f(&iter.collect::<Vec<_>>()).

§

type Output = R

§

impl<T> Filterable for T

§

fn filterable( self, filter_name: &'static str ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<P> IntoQueryParam<P> for P

source§

impl<T> MaybeResult<T> for T

§

type Error = !

source§

fn from(_: Result<T, <T as MaybeResult<T>>::Error>) -> T

source§

fn to_result(self) -> Result<T, <T as MaybeResult<T>>::Error>

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<'tcx, T> ToPredicate<'tcx, T> for T

source§

fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> T

source§

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

§

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

§

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

§

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

§

fn vzip(self) -> V

source§

impl<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

source§

default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed ) -> T

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

§

impl<T> ErasedDestructor for T
where T: 'static,

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: 328 bytes