summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys/sgx
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys/sgx')
-rw-r--r--library/std/src/sys/sgx/condvar.rs29
-rw-r--r--library/std/src/sys/sgx/mod.rs1
-rw-r--r--library/std/src/sys/sgx/mutex.rs24
-rw-r--r--library/std/src/sys/sgx/rwlock.rs78
-rw-r--r--library/std/src/sys/sgx/rwlock/tests.rs16
5 files changed, 75 insertions, 73 deletions
diff --git a/library/std/src/sys/sgx/condvar.rs b/library/std/src/sys/sgx/condvar.rs
index 36534e0ef..aa1174664 100644
--- a/library/std/src/sys/sgx/condvar.rs
+++ b/library/std/src/sys/sgx/condvar.rs
@@ -4,42 +4,43 @@ use crate::time::Duration;
use super::waitqueue::{SpinMutex, WaitQueue, WaitVariable};
+/// FIXME: `UnsafeList` is not movable.
+struct AllocatedCondvar(SpinMutex<WaitVariable<()>>);
+
pub struct Condvar {
- inner: SpinMutex<WaitVariable<()>>,
+ inner: LazyBox<AllocatedCondvar>,
}
-pub(crate) type MovableCondvar = LazyBox<Condvar>;
-
-impl LazyInit for Condvar {
+impl LazyInit for AllocatedCondvar {
fn init() -> Box<Self> {
- Box::new(Self::new())
+ Box::new(AllocatedCondvar(SpinMutex::new(WaitVariable::new(()))))
}
}
impl Condvar {
pub const fn new() -> Condvar {
- Condvar { inner: SpinMutex::new(WaitVariable::new(())) }
+ Condvar { inner: LazyBox::new() }
}
#[inline]
- pub unsafe fn notify_one(&self) {
- let _ = WaitQueue::notify_one(self.inner.lock());
+ pub fn notify_one(&self) {
+ let _ = WaitQueue::notify_one(self.inner.0.lock());
}
#[inline]
- pub unsafe fn notify_all(&self) {
- let _ = WaitQueue::notify_all(self.inner.lock());
+ pub fn notify_all(&self) {
+ let _ = WaitQueue::notify_all(self.inner.0.lock());
}
pub unsafe fn wait(&self, mutex: &Mutex) {
- let guard = self.inner.lock();
+ let guard = self.inner.0.lock();
WaitQueue::wait(guard, || unsafe { mutex.unlock() });
- unsafe { mutex.lock() }
+ mutex.lock()
}
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
- let success = WaitQueue::wait_timeout(&self.inner, dur, || unsafe { mutex.unlock() });
- unsafe { mutex.lock() };
+ let success = WaitQueue::wait_timeout(&self.inner.0, dur, || unsafe { mutex.unlock() });
+ mutex.lock();
success
}
}
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index b1d32929e..01e4ffe3d 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -3,6 +3,7 @@
//! This module contains the facade (aka platform-specific) implementations of
//! OS level functionality for Fortanix SGX.
#![deny(unsafe_op_in_unsafe_fn)]
+#![allow(fuzzy_provenance_casts)] // FIXME: this entire module systematically confuses pointers and integers
use crate::io::ErrorKind;
use crate::sync::atomic::{AtomicBool, Ordering};
diff --git a/library/std/src/sys/sgx/mutex.rs b/library/std/src/sys/sgx/mutex.rs
index aa747d56b..0dbf020eb 100644
--- a/library/std/src/sys/sgx/mutex.rs
+++ b/library/std/src/sys/sgx/mutex.rs
@@ -1,28 +1,28 @@
use super::waitqueue::{try_lock_or_false, SpinMutex, WaitQueue, WaitVariable};
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
+/// FIXME: `UnsafeList` is not movable.
+struct AllocatedMutex(SpinMutex<WaitVariable<bool>>);
+
pub struct Mutex {
- inner: SpinMutex<WaitVariable<bool>>,
+ inner: LazyBox<AllocatedMutex>,
}
-// not movable: see UnsafeList implementation
-pub(crate) type MovableMutex = LazyBox<Mutex>;
-
-impl LazyInit for Mutex {
+impl LazyInit for AllocatedMutex {
fn init() -> Box<Self> {
- Box::new(Self::new())
+ Box::new(AllocatedMutex(SpinMutex::new(WaitVariable::new(false))))
}
}
// Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28
impl Mutex {
pub const fn new() -> Mutex {
- Mutex { inner: SpinMutex::new(WaitVariable::new(false)) }
+ Mutex { inner: LazyBox::new() }
}
#[inline]
- pub unsafe fn lock(&self) {
- let mut guard = self.inner.lock();
+ pub fn lock(&self) {
+ let mut guard = self.inner.0.lock();
if *guard.lock_var() {
// Another thread has the lock, wait
WaitQueue::wait(guard, || {})
@@ -35,7 +35,7 @@ impl Mutex {
#[inline]
pub unsafe fn unlock(&self) {
- let guard = self.inner.lock();
+ let guard = self.inner.0.lock();
if let Err(mut guard) = WaitQueue::notify_one(guard) {
// No other waiters, unlock
*guard.lock_var_mut() = false;
@@ -45,8 +45,8 @@ impl Mutex {
}
#[inline]
- pub unsafe fn try_lock(&self) -> bool {
- let mut guard = try_lock_or_false!(self.inner);
+ pub fn try_lock(&self) -> bool {
+ let mut guard = try_lock_or_false!(self.inner.0);
if *guard.lock_var() {
// Another thread has the lock
false
diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs
index a97fb9ab0..d89de18ca 100644
--- a/library/std/src/sys/sgx/rwlock.rs
+++ b/library/std/src/sys/sgx/rwlock.rs
@@ -7,42 +7,45 @@ use crate::sys_common::lazy_box::{LazyBox, LazyInit};
use super::waitqueue::{
try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable,
};
-use crate::mem;
+use crate::alloc::Layout;
-pub struct RwLock {
+struct AllocatedRwLock {
readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>,
writer: SpinMutex<WaitVariable<bool>>,
}
-pub(crate) type MovableRwLock = LazyBox<RwLock>;
+pub struct RwLock {
+ inner: LazyBox<AllocatedRwLock>,
+}
-impl LazyInit for RwLock {
+impl LazyInit for AllocatedRwLock {
fn init() -> Box<Self> {
- Box::new(Self::new())
+ Box::new(AllocatedRwLock {
+ readers: SpinMutex::new(WaitVariable::new(None)),
+ writer: SpinMutex::new(WaitVariable::new(false)),
+ })
}
}
-// Check at compile time that RwLock size matches C definition (see test_c_rwlock_initializer below)
-//
-// # Safety
-// Never called, as it is a compile time check.
-#[allow(dead_code)]
-unsafe fn rw_lock_size_assert(r: RwLock) {
- unsafe { mem::transmute::<RwLock, [u8; 144]>(r) };
-}
+// Check at compile time that RwLock's size and alignment matches the C definition
+// in libunwind (see also `test_c_rwlock_initializer` in `tests`).
+const _: () = {
+ let rust = Layout::new::<RwLock>();
+ let c = Layout::new::<*mut ()>();
+ assert!(rust.size() == c.size());
+ assert!(rust.align() == c.align());
+};
impl RwLock {
pub const fn new() -> RwLock {
- RwLock {
- readers: SpinMutex::new(WaitVariable::new(None)),
- writer: SpinMutex::new(WaitVariable::new(false)),
- }
+ RwLock { inner: LazyBox::new() }
}
#[inline]
- pub unsafe fn read(&self) {
- let mut rguard = self.readers.lock();
- let wguard = self.writer.lock();
+ pub fn read(&self) {
+ let lock = &*self.inner;
+ let mut rguard = lock.readers.lock();
+ let wguard = lock.writer.lock();
if *wguard.lock_var() || !wguard.queue_empty() {
// Another thread has or is waiting for the write lock, wait
drop(wguard);
@@ -57,8 +60,9 @@ impl RwLock {
#[inline]
pub unsafe fn try_read(&self) -> bool {
- let mut rguard = try_lock_or_false!(self.readers);
- let wguard = try_lock_or_false!(self.writer);
+ let lock = &*self.inner;
+ let mut rguard = try_lock_or_false!(lock.readers);
+ let wguard = try_lock_or_false!(lock.writer);
if *wguard.lock_var() || !wguard.queue_empty() {
// Another thread has or is waiting for the write lock
false
@@ -71,9 +75,10 @@ impl RwLock {
}
#[inline]
- pub unsafe fn write(&self) {
- let rguard = self.readers.lock();
- let mut wguard = self.writer.lock();
+ pub fn write(&self) {
+ let lock = &*self.inner;
+ let rguard = lock.readers.lock();
+ let mut wguard = lock.writer.lock();
if *wguard.lock_var() || rguard.lock_var().is_some() {
// Another thread has the lock, wait
drop(rguard);
@@ -86,9 +91,10 @@ impl RwLock {
}
#[inline]
- pub unsafe fn try_write(&self) -> bool {
- let rguard = try_lock_or_false!(self.readers);
- let mut wguard = try_lock_or_false!(self.writer);
+ pub fn try_write(&self) -> bool {
+ let lock = &*self.inner;
+ let rguard = try_lock_or_false!(lock.readers);
+ let mut wguard = try_lock_or_false!(lock.writer);
if *wguard.lock_var() || rguard.lock_var().is_some() {
// Another thread has the lock
false
@@ -122,8 +128,9 @@ impl RwLock {
#[inline]
pub unsafe fn read_unlock(&self) {
- let rguard = self.readers.lock();
- let wguard = self.writer.lock();
+ let lock = &*self.inner;
+ let rguard = lock.readers.lock();
+ let wguard = lock.writer.lock();
unsafe { self.__read_unlock(rguard, wguard) };
}
@@ -158,8 +165,9 @@ impl RwLock {
#[inline]
pub unsafe fn write_unlock(&self) {
- let rguard = self.readers.lock();
- let wguard = self.writer.lock();
+ let lock = &*self.inner;
+ let rguard = lock.readers.lock();
+ let wguard = lock.writer.lock();
unsafe { self.__write_unlock(rguard, wguard) };
}
@@ -167,8 +175,9 @@ impl RwLock {
#[inline]
#[cfg_attr(test, allow(dead_code))]
unsafe fn unlock(&self) {
- let rguard = self.readers.lock();
- let wguard = self.writer.lock();
+ let lock = &*self.inner;
+ let rguard = lock.readers.lock();
+ let wguard = lock.writer.lock();
if *wguard.lock_var() == true {
unsafe { self.__write_unlock(rguard, wguard) };
} else {
@@ -201,6 +210,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 {
unsafe { (*p).write() };
return 0;
}
+
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 {
diff --git a/library/std/src/sys/sgx/rwlock/tests.rs b/library/std/src/sys/sgx/rwlock/tests.rs
index 479996115..5fd6670af 100644
--- a/library/std/src/sys/sgx/rwlock/tests.rs
+++ b/library/std/src/sys/sgx/rwlock/tests.rs
@@ -1,22 +1,12 @@
use super::*;
+use crate::ptr;
// Verify that the byte pattern libunwind uses to initialize an RwLock is
// equivalent to the value of RwLock::new(). If the value changes,
// `src/UnwindRustSgx.h` in libunwind needs to be changed too.
#[test]
fn test_c_rwlock_initializer() {
- #[rustfmt::skip]
- const C_RWLOCK_INIT: &[u8] = &[
- /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- ];
+ const C_RWLOCK_INIT: *mut () = ptr::null_mut();
// For the test to work, we need the padding/unused bytes in RwLock to be
// initialized as 0. In practice, this is the case with statics.
@@ -26,6 +16,6 @@ fn test_c_rwlock_initializer() {
// If the assertion fails, that not necessarily an issue with the value
// of C_RWLOCK_INIT. It might just be an issue with the way padding
// bytes are initialized in the test code.
- assert_eq!(&crate::mem::transmute_copy::<_, [u8; 144]>(&RUST_RWLOCK_INIT), C_RWLOCK_INIT);
+ assert_eq!(crate::mem::transmute_copy::<_, *mut ()>(&RUST_RWLOCK_INIT), C_RWLOCK_INIT);
};
}