## GlobalState

# Struct GlobalState

Source

    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>>,
        last_sc_fence: RefCell<VClock>,
        last_sc_write_per_thread: RefCell<VClock>,
        pub track_outdated_loads: bool,
        pub weak_memory: 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.

§`last_sc_fence: RefCell<VClock>`

We make SC fences act like RMWs on a global location. To implement that, they all release and acquire into this clock.

§`last_sc_write_per_thread: RefCell<VClock>`

The timestamp of last SC write performed by each thread. Threads only update their own index here!

§`track_outdated_loads: bool`

Track when an outdated (weak memory) load happens.

§`weak_memory: bool`

Whether weak memory emulation is enabled

## 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, threads: &ThreadManager<'_>, 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<'_>)

On thread termination, the vector clock may be 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 atomic_fence<'tcx>( &self, machine: &MiriMachine<'tcx>, atomic: AtomicFenceOrd, ) -> InterpResult<'tcx>

Update the data-race detector for an atomic fence on the current thread.

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 acquire_clock<'tcx>(&self, clock: &VClock, threads: &ThreadManager<'tcx>)

Acquire the given clock into the current thread, establishing synchronization with the moment when that clock snapshot was taken via `release_clock`. As this is an acquire operation, the thread timestamp is not incremented.

Source

#### pub fn release_clock<'tcx, R>( &self, threads: &ThreadManager<'tcx>, callback: impl FnOnce(&VClock) -> R, ) -> R

Calls the given closure with the “release” clock of the current thread. Other threads can acquire this clock in the future to establish synchronization with this program point.

Source

#### fn thread_index(&self, thread: ThreadId) -> VectorIdx

Source

#### fn 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

#### fn thread_state(&self, thread: ThreadId) -> (VectorIdx, Ref<'_, 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 active_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 active_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 active_thread_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 duplicate of the value. Read more
1.0.0§

#### 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§

§

### impl !Freeze for GlobalState

§

### impl !RefUnwindSafe for GlobalState

§

### impl Send for GlobalState

§

### impl !Sync for GlobalState

§

### impl Unpin for GlobalState

§

### impl UnwindSafe for GlobalState

## Blanket Implementations§

§

### impl<T> Any for T
where T: 'static + ?Sized,

§

#### fn type_id(&self) -> TypeId

Gets the `TypeId` of `self`. Read more
§

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

§

#### fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

### impl<T> CloneToUninit for T
where T: Clone,

§

#### unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (`clone_to_uninit`)
Performs copy-assignment from `self` to `dest`. Read more
§

### impl<T> From<T> for T

§

#### fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

#### fn into(self) -> U

Calls `U::from(self)`.

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

§

### impl<T> Same for T

§

#### type Output = T

Should always be `Self`
§

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

§

#### type Owned = T

The resulting type after obtaining ownership.
§

#### fn to_owned(&self) -> T

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

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

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

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

§

#### type Error = Infallible

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

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

Performs the conversion.
§

### 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.
§

#### 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: 288 bytes