diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2020-10-01 01:06:35 +0200 |
|---|---|---|
| committer | Mara Bos <m-ou.se@m-ou.se> | 2020-10-02 09:47:08 +0200 |
| commit | 58deb7001deceb74cec38590a161d781d5d953b4 (patch) | |
| tree | 27097158ebb5b75a191b13c903d15d5fda0a3140 /library/std/src | |
| parent | a8c2d4fc3d29496aa0a3563ec9d44f6222597fe3 (diff) | |
| download | rust-58deb7001deceb74cec38590a161d781d5d953b4.tar.gz rust-58deb7001deceb74cec38590a161d781d5d953b4.zip | |
Make it possible to have unboxed mutexes on specific platforms.
This commit keeps all mutexes boxed on all platforms, but makes it trivial to remove the box on some platforms later.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/sys/cloudabi/mutex.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/mutex.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/unix/mutex.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/mutex.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/vxworks/mutex.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasm/mutex_atomics.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/windows/mutex.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys_common/condvar.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys_common/condvar/check.rs | 33 | ||||
| -rw-r--r-- | library/std/src/sys_common/mutex.rs | 9 |
10 files changed, 51 insertions, 9 deletions
diff --git a/library/std/src/sys/cloudabi/mutex.rs b/library/std/src/sys/cloudabi/mutex.rs index 580ab0e8ad8..651ac3c4cbe 100644 --- a/library/std/src/sys/cloudabi/mutex.rs +++ b/library/std/src/sys/cloudabi/mutex.rs @@ -15,6 +15,8 @@ extern "C" { // implemented identically. pub struct Mutex(RWLock); +pub type MovableMutex = Box<Mutex>; + pub unsafe fn raw(m: &Mutex) -> *mut AtomicU32 { rwlock::raw(&m.0) } diff --git a/library/std/src/sys/sgx/mutex.rs b/library/std/src/sys/sgx/mutex.rs index 4911c2f5387..8874517dac6 100644 --- a/library/std/src/sys/sgx/mutex.rs +++ b/library/std/src/sys/sgx/mutex.rs @@ -8,6 +8,8 @@ pub struct Mutex { inner: SpinMutex<WaitVariable<bool>>, } +pub type MovableMutex = Box<Mutex>; + // Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28 impl Mutex { pub const fn new() -> Mutex { diff --git a/library/std/src/sys/unix/mutex.rs b/library/std/src/sys/unix/mutex.rs index 45c600f75f5..ebc737b75ae 100644 --- a/library/std/src/sys/unix/mutex.rs +++ b/library/std/src/sys/unix/mutex.rs @@ -5,6 +5,8 @@ pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t>, } +pub type MovableMutex = Box<Mutex>; + #[inline] pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t { m.inner.get() diff --git a/library/std/src/sys/unsupported/mutex.rs b/library/std/src/sys/unsupported/mutex.rs index 9ef8af52eb5..a28f2cf4ffe 100644 --- a/library/std/src/sys/unsupported/mutex.rs +++ b/library/std/src/sys/unsupported/mutex.rs @@ -4,6 +4,8 @@ pub struct Mutex { locked: UnsafeCell<bool>, } +pub type MovableMutex = Box<Mutex>; + unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} // no threads on this platform diff --git a/library/std/src/sys/vxworks/mutex.rs b/library/std/src/sys/vxworks/mutex.rs index 103d87e3d2f..dd7582c21a7 100644 --- a/library/std/src/sys/vxworks/mutex.rs +++ b/library/std/src/sys/vxworks/mutex.rs @@ -5,6 +5,8 @@ pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t>, } +pub type MovableMutex = Box<Mutex>; + #[inline] pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t { m.inner.get() diff --git a/library/std/src/sys/wasm/mutex_atomics.rs b/library/std/src/sys/wasm/mutex_atomics.rs index 4b1a7c9b481..5d45efe19c2 100644 --- a/library/std/src/sys/wasm/mutex_atomics.rs +++ b/library/std/src/sys/wasm/mutex_atomics.rs @@ -8,6 +8,8 @@ pub struct Mutex { locked: AtomicUsize, } +pub type MovableMutex = Box<Mutex>; + // Mutexes have a pretty simple implementation where they contain an `i32` // internally that is 0 when unlocked and 1 when the mutex is locked. // Acquisition has a fast path where it attempts to cmpxchg the 0 to a 1, and diff --git a/library/std/src/sys/windows/mutex.rs b/library/std/src/sys/windows/mutex.rs index e2aaca59fe2..fb6bb9583e2 100644 --- a/library/std/src/sys/windows/mutex.rs +++ b/library/std/src/sys/windows/mutex.rs @@ -29,6 +29,8 @@ pub struct Mutex { lock: AtomicUsize, } +pub type MovableMutex = Box<Mutex>; + unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} diff --git a/library/std/src/sys_common/condvar.rs b/library/std/src/sys_common/condvar.rs index c65f1f81509..acd8b69e9ac 100644 --- a/library/std/src/sys_common/condvar.rs +++ b/library/std/src/sys_common/condvar.rs @@ -1,10 +1,12 @@ use crate::sys::condvar as imp; +use crate::sys::mutex as mutex_imp; use crate::sys_common::mutex::MovableMutex; use crate::time::Duration; -use check::CondvarCheck; mod check; +type CondvarCheck = <mutex_imp::MovableMutex as check::CondvarCheck>::Check; + /// An OS-based condition variable. pub struct Condvar { inner: Box<imp::Condvar>, diff --git a/library/std/src/sys_common/condvar/check.rs b/library/std/src/sys_common/condvar/check.rs index 949b53f30b1..fecb732b910 100644 --- a/library/std/src/sys_common/condvar/check.rs +++ b/library/std/src/sys_common/condvar/check.rs @@ -2,13 +2,22 @@ use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::mutex as mutex_imp; use crate::sys_common::mutex::MovableMutex; -/// A `Condvar` will check it's only ever used with the same mutex, based on -/// its (stable) address. -pub struct CondvarCheck { +pub trait CondvarCheck { + type Check; +} + +/// For boxed mutexes, a `Condvar` will check it's only ever used with the same +/// mutex, based on its (stable) address. +impl CondvarCheck for Box<mutex_imp::Mutex> { + type Check = SameMutexCheck; +} + +pub struct SameMutexCheck { addr: AtomicUsize, } -impl CondvarCheck { +#[allow(dead_code)] +impl SameMutexCheck { pub const fn new() -> Self { Self { addr: AtomicUsize::new(0) } } @@ -21,3 +30,19 @@ impl CondvarCheck { } } } + +/// Unboxed mutexes may move, so `Condvar` can not require its address to stay +/// constant. +impl CondvarCheck for mutex_imp::Mutex { + type Check = NoCheck; +} + +pub struct NoCheck; + +#[allow(dead_code)] +impl NoCheck { + pub const fn new() -> Self { + Self + } + pub fn verify(&self, _: &MovableMutex) {} +} diff --git a/library/std/src/sys_common/mutex.rs b/library/std/src/sys_common/mutex.rs index e30163b3a89..a1e11d24465 100644 --- a/library/std/src/sys_common/mutex.rs +++ b/library/std/src/sys_common/mutex.rs @@ -58,16 +58,17 @@ impl Drop for StaticMutexGuard<'_> { /// /// This mutex does not implement poisoning. /// -/// This is a wrapper around `Box<imp::Mutex>`, to allow the object to be moved -/// without moving the raw mutex. -pub struct MovableMutex(Box<imp::Mutex>); +/// This is either a wrapper around `Box<imp::Mutex>` or `imp::Mutex`, +/// depending on the platform. It is boxed on platforms where `imp::Mutex` may +/// not be moved. +pub struct MovableMutex(imp::MovableMutex); unsafe impl Sync for MovableMutex {} impl MovableMutex { /// Creates a new mutex. pub fn new() -> Self { - let mut mutex = box imp::Mutex::new(); + let mut mutex = imp::MovableMutex::from(imp::Mutex::new()); unsafe { mutex.init() }; Self(mutex) } |
