about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2024-02-15 17:40:33 +0100
committerjoboet <jonasboettiger@icloud.com>2024-02-16 12:10:49 +0100
commit491d1a76646123e1d68e32ab4e52ddbe6065d82a (patch)
tree406b8d1d622d9029fa8c6709eefbd68e62c60b3e
parent5e343e76e85c7e11afdcf9d76f0b355bbb38153d (diff)
downloadrust-491d1a76646123e1d68e32ab4e52ddbe6065d82a.tar.gz
rust-491d1a76646123e1d68e32ab4e52ddbe6065d82a.zip
std: move locks to `sys` on UNIX and other futex platforms
-rw-r--r--library/std/src/sys/locks/condvar/futex.rs (renamed from library/std/src/sys/pal/unix/locks/futex_condvar.rs)2
-rw-r--r--library/std/src/sys/locks/condvar/mod.rs17
-rw-r--r--library/std/src/sys/locks/condvar/pthread.rs (renamed from library/std/src/sys/pal/unix/locks/pthread_condvar.rs)8
-rw-r--r--library/std/src/sys/locks/mutex/fuchsia.rs (renamed from library/std/src/sys/pal/unix/locks/fuchsia_mutex.rs)0
-rw-r--r--library/std/src/sys/locks/mutex/futex.rs (renamed from library/std/src/sys/pal/unix/locks/futex_mutex.rs)0
-rw-r--r--library/std/src/sys/locks/mutex/mod.rs19
-rw-r--r--library/std/src/sys/locks/rwlock/futex.rs (renamed from library/std/src/sys/pal/unix/locks/futex_rwlock.rs)0
-rw-r--r--library/std/src/sys/locks/rwlock/mod.rs17
-rw-r--r--library/std/src/sys/locks/rwlock/queue.rs (renamed from library/std/src/sys/pal/unix/locks/queue_rwlock.rs)0
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs10
-rw-r--r--library/std/src/sys/pal/unix/locks/mod.rs31
-rw-r--r--library/std/src/sys/pal/unix/locks/pthread_mutex.rs148
-rw-r--r--library/std/src/sys/pal/unix/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs10
-rw-r--r--library/std/src/sys/pal/wasm/mod.rs10
15 files changed, 55 insertions, 218 deletions
diff --git a/library/std/src/sys/pal/unix/locks/futex_condvar.rs b/library/std/src/sys/locks/condvar/futex.rs
index 4bd65dd25c2..3ad93ce07f7 100644
--- a/library/std/src/sys/pal/unix/locks/futex_condvar.rs
+++ b/library/std/src/sys/locks/condvar/futex.rs
@@ -1,6 +1,6 @@
-use super::Mutex;
 use crate::sync::atomic::{AtomicU32, Ordering::Relaxed};
 use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all};
+use crate::sys::locks::Mutex;
 use crate::time::Duration;
 
 pub struct Condvar {
diff --git a/library/std/src/sys/locks/condvar/mod.rs b/library/std/src/sys/locks/condvar/mod.rs
index 74494cdf66d..8bae14b5765 100644
--- a/library/std/src/sys/locks/condvar/mod.rs
+++ b/library/std/src/sys/locks/condvar/mod.rs
@@ -1,5 +1,20 @@
 cfg_if::cfg_if! {
-    if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
+    if #[cfg(any(
+        target_os = "linux",
+        target_os = "android",
+        target_os = "freebsd",
+        target_os = "openbsd",
+        target_os = "dragonfly",
+        target_os = "fuchsia",
+        all(target_family = "wasm", target_feature = "atomics"),
+        target_os = "hermit",
+    ))] {
+        mod futex;
+        pub use futex::Condvar;
+    } else if #[cfg(target_family = "unix")] {
+        mod pthread;
+        pub use pthread::Condvar;
+    } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
         mod sgx;
         pub use sgx::Condvar;
     } else if #[cfg(target_os = "solid_asp3")] {
diff --git a/library/std/src/sys/pal/unix/locks/pthread_condvar.rs b/library/std/src/sys/locks/condvar/pthread.rs
index 2dc1b0c601e..094738d5a3f 100644
--- a/library/std/src/sys/pal/unix/locks/pthread_condvar.rs
+++ b/library/std/src/sys/locks/condvar/pthread.rs
@@ -1,7 +1,7 @@
 use crate::cell::UnsafeCell;
 use crate::ptr;
 use crate::sync::atomic::{AtomicPtr, Ordering::Relaxed};
-use crate::sys::locks::{pthread_mutex, Mutex};
+use crate::sys::locks::{mutex, Mutex};
 #[cfg(not(target_os = "nto"))]
 use crate::sys::time::TIMESPEC_MAX;
 #[cfg(target_os = "nto")]
@@ -112,7 +112,7 @@ impl Condvar {
 
     #[inline]
     pub unsafe fn wait(&self, mutex: &Mutex) {
-        let mutex = pthread_mutex::raw(mutex);
+        let mutex = mutex::raw(mutex);
         self.verify(mutex);
         let r = libc::pthread_cond_wait(raw(self), mutex);
         debug_assert_eq!(r, 0);
@@ -134,7 +134,7 @@ impl Condvar {
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use crate::sys::time::Timespec;
 
-        let mutex = pthread_mutex::raw(mutex);
+        let mutex = mutex::raw(mutex);
         self.verify(mutex);
 
         #[cfg(not(target_os = "nto"))]
@@ -170,7 +170,7 @@ impl Condvar {
         use crate::sys::time::SystemTime;
         use crate::time::Instant;
 
-        let mutex = pthread_mutex::raw(mutex);
+        let mutex = mutex::raw(mutex);
         self.verify(mutex);
 
         // OSX implementation of `pthread_cond_timedwait` is buggy
diff --git a/library/std/src/sys/pal/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/locks/mutex/fuchsia.rs
index 5d89e5a13fd..5d89e5a13fd 100644
--- a/library/std/src/sys/pal/unix/locks/fuchsia_mutex.rs
+++ b/library/std/src/sys/locks/mutex/fuchsia.rs
diff --git a/library/std/src/sys/pal/unix/locks/futex_mutex.rs b/library/std/src/sys/locks/mutex/futex.rs
index c01229586c3..c01229586c3 100644
--- a/library/std/src/sys/pal/unix/locks/futex_mutex.rs
+++ b/library/std/src/sys/locks/mutex/futex.rs
diff --git a/library/std/src/sys/locks/mutex/mod.rs b/library/std/src/sys/locks/mutex/mod.rs
index b94608c849f..170eb6be98c 100644
--- a/library/std/src/sys/locks/mutex/mod.rs
+++ b/library/std/src/sys/locks/mutex/mod.rs
@@ -1,5 +1,22 @@
 cfg_if::cfg_if! {
-    if #[cfg(target_os = "teeos")] {
+    if #[cfg(any(
+        target_os = "linux",
+        target_os = "android",
+        target_os = "freebsd",
+        target_os = "openbsd",
+        target_os = "dragonfly",
+        all(target_family = "wasm", target_feature = "atomics"),
+        target_os = "hermit",
+    ))] {
+        mod futex;
+        pub use futex::Mutex;
+    } else if #[cfg(target_os = "fuchsia")] {
+        mod fuchsia;
+        pub use fuchsia::Mutex;
+    } else if #[cfg(any(
+        target_family = "unix",
+        target_os = "teeos",
+    ))] {
         mod pthread;
         pub use pthread::{Mutex, raw};
     } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
diff --git a/library/std/src/sys/pal/unix/locks/futex_rwlock.rs b/library/std/src/sys/locks/rwlock/futex.rs
index aa0de900238..aa0de900238 100644
--- a/library/std/src/sys/pal/unix/locks/futex_rwlock.rs
+++ b/library/std/src/sys/locks/rwlock/futex.rs
diff --git a/library/std/src/sys/locks/rwlock/mod.rs b/library/std/src/sys/locks/rwlock/mod.rs
index 7de4a9d50a8..96a086fc64b 100644
--- a/library/std/src/sys/locks/rwlock/mod.rs
+++ b/library/std/src/sys/locks/rwlock/mod.rs
@@ -1,5 +1,20 @@
 cfg_if::cfg_if! {
-    if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
+    if #[cfg(any(
+        target_os = "linux",
+        target_os = "android",
+        target_os = "freebsd",
+        target_os = "openbsd",
+        target_os = "dragonfly",
+        target_os = "fuchsia",
+        all(target_family = "wasm", target_feature = "atomics"),
+        target_os = "hermit",
+    ))] {
+        mod futex;
+        pub use futex::RwLock;
+    } else if #[cfg(target_family = "unix")] {
+        mod queue;
+        pub use queue::RwLock;
+    } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
         mod sgx;
         pub use sgx::RwLock;
     } else if #[cfg(target_os = "solid_asp3")] {
diff --git a/library/std/src/sys/pal/unix/locks/queue_rwlock.rs b/library/std/src/sys/locks/rwlock/queue.rs
index 0f02a98dfdd..0f02a98dfdd 100644
--- a/library/std/src/sys/pal/unix/locks/queue_rwlock.rs
+++ b/library/std/src/sys/locks/rwlock/queue.rs
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index 57cc656e266..ada408107dc 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -39,16 +39,6 @@ pub mod thread_local_dtor;
 pub mod thread_local_key;
 pub mod time;
 
-#[path = "../unix/locks"]
-pub mod locks {
-    mod futex_condvar;
-    mod futex_mutex;
-    mod futex_rwlock;
-    pub(crate) use futex_condvar::Condvar;
-    pub(crate) use futex_mutex::Mutex;
-    pub(crate) use futex_rwlock::RwLock;
-}
-
 use crate::io::ErrorKind;
 use crate::os::hermit::abi;
 
diff --git a/library/std/src/sys/pal/unix/locks/mod.rs b/library/std/src/sys/pal/unix/locks/mod.rs
deleted file mode 100644
index a49247310b5..00000000000
--- a/library/std/src/sys/pal/unix/locks/mod.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-cfg_if::cfg_if! {
-    if #[cfg(any(
-        target_os = "linux",
-        target_os = "android",
-        all(target_os = "emscripten", target_feature = "atomics"),
-        target_os = "freebsd",
-        target_os = "openbsd",
-        target_os = "dragonfly",
-    ))] {
-        mod futex_mutex;
-        mod futex_rwlock;
-        mod futex_condvar;
-        pub(crate) use futex_mutex::Mutex;
-        pub(crate) use futex_rwlock::RwLock;
-        pub(crate) use futex_condvar::Condvar;
-    } else if #[cfg(target_os = "fuchsia")] {
-        mod fuchsia_mutex;
-        mod futex_rwlock;
-        mod futex_condvar;
-        pub(crate) use fuchsia_mutex::Mutex;
-        pub(crate) use futex_rwlock::RwLock;
-        pub(crate) use futex_condvar::Condvar;
-    } else {
-        mod pthread_mutex;
-        mod pthread_condvar;
-        mod queue_rwlock;
-        pub(crate) use pthread_mutex::Mutex;
-        pub(crate) use queue_rwlock::RwLock;
-        pub(crate) use pthread_condvar::Condvar;
-    }
-}
diff --git a/library/std/src/sys/pal/unix/locks/pthread_mutex.rs b/library/std/src/sys/pal/unix/locks/pthread_mutex.rs
deleted file mode 100644
index ee0794334fb..00000000000
--- a/library/std/src/sys/pal/unix/locks/pthread_mutex.rs
+++ /dev/null
@@ -1,148 +0,0 @@
-use crate::cell::UnsafeCell;
-use crate::io::Error;
-use crate::mem::{forget, MaybeUninit};
-use crate::sys::cvt_nz;
-use crate::sys_common::lazy_box::{LazyBox, LazyInit};
-
-struct AllocatedMutex(UnsafeCell<libc::pthread_mutex_t>);
-
-pub struct Mutex {
-    inner: LazyBox<AllocatedMutex>,
-}
-
-#[inline]
-pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t {
-    m.inner.0.get()
-}
-
-unsafe impl Send for AllocatedMutex {}
-unsafe impl Sync for AllocatedMutex {}
-
-impl LazyInit for AllocatedMutex {
-    fn init() -> Box<Self> {
-        let mutex = Box::new(AllocatedMutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER)));
-
-        // Issue #33770
-        //
-        // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have
-        // a type of PTHREAD_MUTEX_DEFAULT, which has undefined behavior if you
-        // try to re-lock it from the same thread when you already hold a lock
-        // (https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_init.html).
-        // This is the case even if PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL
-        // (https://github.com/rust-lang/rust/issues/33770#issuecomment-220847521) -- in that
-        // case, `pthread_mutexattr_settype(PTHREAD_MUTEX_DEFAULT)` will of course be the same
-        // as setting it to `PTHREAD_MUTEX_NORMAL`, but not setting any mode will result in
-        // a Mutex where re-locking is UB.
-        //
-        // In practice, glibc takes advantage of this undefined behavior to
-        // implement hardware lock elision, which uses hardware transactional
-        // memory to avoid acquiring the lock. While a transaction is in
-        // progress, the lock appears to be unlocked. This isn't a problem for
-        // other threads since the transactional memory will abort if a conflict
-        // is detected, however no abort is generated when re-locking from the
-        // same thread.
-        //
-        // Since locking the same mutex twice will result in two aliasing &mut
-        // references, we instead create the mutex with type
-        // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
-        // re-lock it from the same thread, thus avoiding undefined behavior.
-        unsafe {
-            let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
-            cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap();
-            let attr = PthreadMutexAttr(&mut attr);
-            cvt_nz(libc::pthread_mutexattr_settype(
-                attr.0.as_mut_ptr(),
-                libc::PTHREAD_MUTEX_NORMAL,
-            ))
-            .unwrap();
-            cvt_nz(libc::pthread_mutex_init(mutex.0.get(), attr.0.as_ptr())).unwrap();
-        }
-
-        mutex
-    }
-
-    fn destroy(mutex: Box<Self>) {
-        // We're not allowed to pthread_mutex_destroy a locked mutex,
-        // so check first if it's unlocked.
-        if unsafe { libc::pthread_mutex_trylock(mutex.0.get()) == 0 } {
-            unsafe { libc::pthread_mutex_unlock(mutex.0.get()) };
-            drop(mutex);
-        } else {
-            // The mutex is locked. This happens if a MutexGuard is leaked.
-            // In this case, we just leak the Mutex too.
-            forget(mutex);
-        }
-    }
-
-    fn cancel_init(_: Box<Self>) {
-        // In this case, we can just drop it without any checks,
-        // since it cannot have been locked yet.
-    }
-}
-
-impl Drop for AllocatedMutex {
-    #[inline]
-    fn drop(&mut self) {
-        let r = unsafe { libc::pthread_mutex_destroy(self.0.get()) };
-        if cfg!(target_os = "dragonfly") {
-            // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a
-            // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER.
-            // Once it is used (locked/unlocked) or pthread_mutex_init() is called,
-            // this behaviour no longer occurs.
-            debug_assert!(r == 0 || r == libc::EINVAL);
-        } else {
-            debug_assert_eq!(r, 0);
-        }
-    }
-}
-
-impl Mutex {
-    #[inline]
-    pub const fn new() -> Mutex {
-        Mutex { inner: LazyBox::new() }
-    }
-
-    #[inline]
-    pub unsafe fn lock(&self) {
-        #[cold]
-        #[inline(never)]
-        fn fail(r: i32) -> ! {
-            let error = Error::from_raw_os_error(r);
-            panic!("failed to lock mutex: {error}");
-        }
-
-        let r = libc::pthread_mutex_lock(raw(self));
-        // As we set the mutex type to `PTHREAD_MUTEX_NORMAL` above, we expect
-        // the lock call to never fail. Unfortunately however, some platforms
-        // (Solaris) do not conform to the standard, and instead always provide
-        // deadlock detection. How kind of them! Unfortunately that means that
-        // we need to check the error code here. To save us from UB on other
-        // less well-behaved platforms in the future, we do it even on "good"
-        // platforms like macOS. See #120147 for more context.
-        if r != 0 {
-            fail(r)
-        }
-    }
-
-    #[inline]
-    pub unsafe fn unlock(&self) {
-        let r = libc::pthread_mutex_unlock(raw(self));
-        debug_assert_eq!(r, 0);
-    }
-
-    #[inline]
-    pub unsafe fn try_lock(&self) -> bool {
-        libc::pthread_mutex_trylock(raw(self)) == 0
-    }
-}
-
-pub(super) struct PthreadMutexAttr<'a>(pub &'a mut MaybeUninit<libc::pthread_mutexattr_t>);
-
-impl Drop for PthreadMutexAttr<'_> {
-    fn drop(&mut self) {
-        unsafe {
-            let result = libc::pthread_mutexattr_destroy(self.0.as_mut_ptr());
-            debug_assert_eq!(result, 0);
-        }
-    }
-}
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 976a437c17f..04b8c5ca916 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -20,7 +20,6 @@ pub mod io;
 pub mod kernel_copy;
 #[cfg(target_os = "l4re")]
 mod l4re;
-pub mod locks;
 pub mod memchr;
 #[cfg(not(target_os = "l4re"))]
 pub mod net;
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index 116878ee996..5de2e0e7d63 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -44,16 +44,6 @@ pub mod time;
 
 cfg_if::cfg_if! {
     if #[cfg(target_feature = "atomics")] {
-        #[path = "../unix/locks"]
-        pub mod locks {
-            #![allow(unsafe_op_in_unsafe_fn)]
-            mod futex_condvar;
-            mod futex_mutex;
-            mod futex_rwlock;
-            pub(crate) use futex_condvar::Condvar;
-            pub(crate) use futex_mutex::Mutex;
-            pub(crate) use futex_rwlock::RwLock;
-        }
     } else {
         #[path = "../unsupported/locks/mod.rs"]
         pub mod locks;
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs
index 567555118d7..910a54b2e01 100644
--- a/library/std/src/sys/pal/wasm/mod.rs
+++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -43,16 +43,6 @@ pub mod time;
 
 cfg_if::cfg_if! {
     if #[cfg(target_feature = "atomics")] {
-        #[path = "../unix/locks"]
-        pub mod locks {
-            #![allow(unsafe_op_in_unsafe_fn)]
-            mod futex_condvar;
-            mod futex_mutex;
-            mod futex_rwlock;
-            pub(crate) use futex_condvar::Condvar;
-            pub(crate) use futex_mutex::Mutex;
-            pub(crate) use futex_rwlock::RwLock;
-        }
         #[path = "atomics/futex.rs"]
         pub mod futex;
         #[path = "atomics/thread.rs"]