correct literals for dyn thread safe
This commit is contained in:
parent
9f8ab2a8d3
commit
089a38880b
11 changed files with 48 additions and 41 deletions
|
@ -8,20 +8,20 @@ cfg_if!(
|
|||
} else {
|
||||
#[rustc_on_unimplemented(
|
||||
message = "`{Self}` doesn't implement `DynSend`. \
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Send`"
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`"
|
||||
)]
|
||||
// This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
|
||||
// is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a
|
||||
// `Send` type in `IntoDyn` will create a `DynSend` type.
|
||||
// `Send` type in `IntoDynSyncSend` will create a `DynSend` type.
|
||||
pub unsafe auto trait DynSend {}
|
||||
|
||||
#[rustc_on_unimplemented(
|
||||
message = "`{Self}` doesn't implement `DynSync`. \
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Sync`"
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Sync`"
|
||||
)]
|
||||
// This is an auto trait for types which can be shared across threads if `sync::is_dyn_thread_safe()`
|
||||
// is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a
|
||||
// `Sync` type in `IntoDyn` will create a `DynSync` type.
|
||||
// `Sync` type in `IntoDynSyncSend` will create a `DynSync` type.
|
||||
pub unsafe auto trait DynSync {}
|
||||
|
||||
// Same with `Sync` and `Send`.
|
||||
|
@ -234,15 +234,18 @@ impl<T> const std::ops::Deref for FromDyn<T> {
|
|||
}
|
||||
}
|
||||
|
||||
// A wrapper to convert a struct that is already a `Send` or `Sync` into
|
||||
// an instance of `DynSend` and `DynSync`, since the compiler cannot infer
|
||||
// it automatically in some cases. (e.g. Box<dyn Send / Sync>)
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct IntoDyn<T: ?Sized>(pub T);
|
||||
pub struct IntoDynSyncSend<T: ?Sized>(pub T);
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl<T: ?Sized + Send> DynSend for IntoDyn<T> {}
|
||||
unsafe impl<T: ?Sized + Send> DynSend for IntoDynSyncSend<T> {}
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl<T: ?Sized + Sync> DynSync for IntoDyn<T> {}
|
||||
unsafe impl<T: ?Sized + Sync> DynSync for IntoDynSyncSend<T> {}
|
||||
|
||||
impl<T> const std::ops::Deref for IntoDyn<T> {
|
||||
impl<T> const std::ops::Deref for IntoDynSyncSend<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
|
@ -250,7 +253,7 @@ impl<T> const std::ops::Deref for IntoDyn<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> const std::ops::DerefMut for IntoDyn<T> {
|
||||
impl<T> const std::ops::DerefMut for IntoDynSyncSend<T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.0
|
||||
}
|
||||
|
|
|
@ -61,25 +61,25 @@ mod mode {
|
|||
use std::sync::atomic::AtomicU8;
|
||||
|
||||
const UNINITIALIZED: u8 = 0;
|
||||
const DYN_NOT_SYNC: u8 = 1;
|
||||
const DYN_SYNC: u8 = 2;
|
||||
const DYN_NOT_THREAD_SAFE: u8 = 1;
|
||||
const DYN_THREAD_SAFE: u8 = 2;
|
||||
|
||||
static DYN_SYNC_MODE: AtomicU8 = AtomicU8::new(UNINITIALIZED);
|
||||
static DYN_THREAD_SAFE_MODE: AtomicU8 = AtomicU8::new(UNINITIALIZED);
|
||||
|
||||
// Weather control thread safety dynamically
|
||||
// Whether thread safety is enabled (due to running under multiple threads).
|
||||
#[inline]
|
||||
pub fn is_dyn_thread_safe() -> bool {
|
||||
match DYN_SYNC_MODE.load(Ordering::Relaxed) {
|
||||
DYN_NOT_SYNC => false,
|
||||
DYN_SYNC => true,
|
||||
_ => panic!("uninitialized parallel mode!"),
|
||||
match DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) {
|
||||
DYN_NOT_THREAD_SAFE => false,
|
||||
DYN_THREAD_SAFE => true,
|
||||
_ => panic!("uninitialized dyn_thread_safe mode!"),
|
||||
}
|
||||
}
|
||||
|
||||
// Only set by the `-Z threads` compile option
|
||||
pub fn set_dyn_thread_safe_mode(parallel: bool) {
|
||||
let set: u8 = if parallel { DYN_SYNC } else { DYN_NOT_SYNC };
|
||||
let previous = DYN_SYNC_MODE.compare_exchange(
|
||||
pub fn set_dyn_thread_safe_mode(mode: bool) {
|
||||
let set: u8 = if mode { DYN_THREAD_SAFE } else { DYN_NOT_THREAD_SAFE };
|
||||
let previous = DYN_THREAD_SAFE_MODE.compare_exchange(
|
||||
UNINITIALIZED,
|
||||
set,
|
||||
Ordering::Relaxed,
|
||||
|
@ -401,7 +401,7 @@ cfg_if! {
|
|||
if rustc_data_structures::sync::is_dyn_thread_safe() {
|
||||
// Reverse the order of the later blocks since Rayon executes them in reverse order
|
||||
// when using a single thread. This ensures the execution order matches that
|
||||
// of a single threaded rustc
|
||||
// of a single threaded rustc.
|
||||
parallel!(impl $fblock [] [$($blocks),*]);
|
||||
} else {
|
||||
// We catch panics here ensuring that all the blocks execute.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue