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/mod.rs1
-rw-r--r--library/std/src/sys/sgx/thread.rs21
-rw-r--r--library/std/src/sys/sgx/thread_parking.rs23
3 files changed, 33 insertions, 12 deletions
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index 01e4ffe3d..9865a945b 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -34,6 +34,7 @@ pub mod process;
pub mod stdio;
pub mod thread;
pub mod thread_local_key;
+pub mod thread_parking;
pub mod time;
mod condvar;
diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs
index d745a6196..1608b8cb6 100644
--- a/library/std/src/sys/sgx/thread.rs
+++ b/library/std/src/sys/sgx/thread.rs
@@ -65,39 +65,36 @@ mod task_queue {
/// execution. The signal is sent once all TLS destructors have finished at
/// which point no new thread locals should be created.
pub mod wait_notify {
- use super::super::waitqueue::{SpinMutex, WaitQueue, WaitVariable};
+ use crate::pin::Pin;
use crate::sync::Arc;
+ use crate::sys_common::thread_parking::Parker;
- pub struct Notifier(Arc<SpinMutex<WaitVariable<bool>>>);
+ pub struct Notifier(Arc<Parker>);
impl Notifier {
/// Notify the waiter. The waiter is either notified right away (if
/// currently blocked in `Waiter::wait()`) or later when it calls the
/// `Waiter::wait()` method.
pub fn notify(self) {
- let mut guard = self.0.lock();
- *guard.lock_var_mut() = true;
- let _ = WaitQueue::notify_one(guard);
+ Pin::new(&*self.0).unpark()
}
}
- pub struct Waiter(Arc<SpinMutex<WaitVariable<bool>>>);
+ pub struct Waiter(Arc<Parker>);
impl Waiter {
/// Wait for a notification. If `Notifier::notify()` has already been
/// called, this will return immediately, otherwise the current thread
/// is blocked until notified.
pub fn wait(self) {
- let guard = self.0.lock();
- if *guard.lock_var() {
- return;
- }
- WaitQueue::wait(guard, || {});
+ // SAFETY:
+ // This is only ever called on one thread.
+ unsafe { Pin::new(&*self.0).park() }
}
}
pub fn new() -> (Notifier, Waiter) {
- let inner = Arc::new(SpinMutex::new(WaitVariable::new(false)));
+ let inner = Arc::new(Parker::new());
(Notifier(inner.clone()), Waiter(inner))
}
}
diff --git a/library/std/src/sys/sgx/thread_parking.rs b/library/std/src/sys/sgx/thread_parking.rs
new file mode 100644
index 000000000..0006cd4f1
--- /dev/null
+++ b/library/std/src/sys/sgx/thread_parking.rs
@@ -0,0 +1,23 @@
+use super::abi::usercalls;
+use crate::io::ErrorKind;
+use crate::time::Duration;
+use fortanix_sgx_abi::{EV_UNPARK, WAIT_INDEFINITE};
+
+pub type ThreadId = fortanix_sgx_abi::Tcs;
+
+pub use super::abi::thread::current;
+
+pub fn park(_hint: usize) {
+ usercalls::wait(EV_UNPARK, WAIT_INDEFINITE).unwrap();
+}
+
+pub fn park_timeout(dur: Duration, _hint: usize) {
+ let timeout = u128::min(dur.as_nanos(), WAIT_INDEFINITE as u128 - 1) as u64;
+ if let Err(e) = usercalls::wait(EV_UNPARK, timeout) {
+ assert!(matches!(e.kind(), ErrorKind::TimedOut | ErrorKind::WouldBlock))
+ }
+}
+
+pub fn unpark(tid: ThreadId, _hint: usize) {
+ let _ = usercalls::send(EV_UNPARK, Some(tid));
+}