about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorMohsen Zohrevandi <mohsen.zohrevandi@fortanix.com>2020-07-15 15:48:36 -0700
committerMohsen Zohrevandi <mohsen.zohrevandi@fortanix.com>2020-07-15 15:48:36 -0700
commit85c25aed510ce599504b172f7c7bef280e91637b (patch)
treea80a4b1cd516f4516cb7ab85027db12ca8c4b6ac /src/libstd/sys
parent1466598e19321bc6b97aef8271a317e78211d54d (diff)
downloadrust-85c25aed510ce599504b172f7c7bef280e91637b.tar.gz
rust-85c25aed510ce599504b172f7c7bef280e91637b.zip
Move usercall_wait_timeout to abi::usercalls::wait_timeout
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/sgx/abi/usercalls/mod.rs74
-rw-r--r--src/libstd/sys/sgx/mod.rs76
-rw-r--r--src/libstd/sys/sgx/thread.rs3
-rw-r--r--src/libstd/sys/sgx/waitqueue.rs3
4 files changed, 74 insertions, 82 deletions
diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs
index 6ee147d1704..73f1b951e74 100644
--- a/src/libstd/sys/sgx/abi/usercalls/mod.rs
+++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs
@@ -1,8 +1,8 @@
 use crate::cmp;
 use crate::convert::TryFrom;
-use crate::io::{Error as IoError, IoSlice, IoSliceMut, Result as IoResult};
+use crate::io::{Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult};
 use crate::sys::rand::rdrand64;
-use crate::time::Duration;
+use crate::time::{Duration, Instant};
 
 pub(crate) mod alloc;
 #[macro_use]
@@ -169,6 +169,76 @@ pub fn wait(event_mask: u64, mut timeout: u64) -> IoResult<u64> {
     unsafe { raw::wait(event_mask, timeout).from_sgx_result() }
 }
 
+/// This function makes an effort to wait for a non-spurious event at least as
+/// long as `duration`. Note that in general there is no guarantee about accuracy
+/// of time and timeouts in SGX model. The enclave runner serving usercalls may
+/// lie about current time and/or ignore timeout values.
+///
+/// Once the event is observed, `should_wake_up` will be used to determine
+/// whether or not the event was spurious.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub fn wait_timeout<F>(event_mask: u64, duration: Duration, should_wake_up: F)
+where
+    F: Fn() -> bool,
+{
+    // Calls the wait usercall and checks the result. Returns true if event was
+    // returned, and false if WouldBlock/TimedOut was returned.
+    // If duration is None, it will use WAIT_NO.
+    fn wait_checked(event_mask: u64, duration: Option<Duration>) -> bool {
+        let timeout = duration.map_or(raw::WAIT_NO, |duration| {
+            cmp::min((u64::MAX - 1) as u128, duration.as_nanos()) as u64
+        });
+        match wait(event_mask, timeout) {
+            Ok(eventset) => {
+                if event_mask == 0 {
+                    rtabort!("expected wait() to return Err, found Ok.");
+                }
+                rtassert!(eventset != 0 && eventset & !event_mask == 0);
+                true
+            }
+            Err(e) => {
+                rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock);
+                false
+            }
+        }
+    }
+
+    match wait_checked(event_mask, Some(duration)) {
+        false => return,                    // timed out
+        true if should_wake_up() => return, // woken up
+        true => {}                          // spurious event
+    }
+
+    // Drain all cached events.
+    // Note that `event_mask != 0` is implied if we get here.
+    loop {
+        match wait_checked(event_mask, None) {
+            false => break,                     // no more cached events
+            true if should_wake_up() => return, // woken up
+            true => {}                          // spurious event
+        }
+    }
+
+    // Continue waiting, but take note of time spent waiting so we don't wait
+    // forever. We intentionally don't call `Instant::now()` before this point
+    // to avoid the cost of the `insecure_time` usercall in case there are no
+    // spurious wakeups.
+
+    let start = Instant::now();
+    let mut remaining = duration;
+    loop {
+        match wait_checked(event_mask, Some(remaining)) {
+            false => return,                    // timed out
+            true if should_wake_up() => return, // woken up
+            true => {}                          // spurious event
+        }
+        remaining = match duration.checked_sub(start.elapsed()) {
+            Some(remaining) => remaining,
+            None => break,
+        }
+    }
+}
+
 /// Usercall `send`. See the ABI documentation for more information.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn send(event_set: u64, tcs: Option<Tcs>) -> IoResult<()> {
diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs
index c412053112b..7a3a3eb2049 100644
--- a/src/libstd/sys/sgx/mod.rs
+++ b/src/libstd/sys/sgx/mod.rs
@@ -110,82 +110,6 @@ pub fn decode_error_kind(code: i32) -> ErrorKind {
     }
 }
 
-// This function makes an effort to wait for a non-spurious event at least as
-// long as `duration`. Note that in general there is no guarantee about accuracy
-// of time and timeouts in SGX model. The enclave runner serving usercalls may
-// lie about current time and/or ignore timeout values.
-//
-// Once the event is observed, `should_wake_up` will be used to determine
-// whether or not the event was spurious.
-pub fn usercall_wait_timeout<F>(event_mask: u64, duration: crate::time::Duration, should_wake_up: F)
-where
-    F: Fn() -> bool,
-{
-    use self::abi::usercalls;
-    use crate::cmp;
-    use crate::io::ErrorKind;
-    use crate::time::{Duration, Instant};
-
-    // Calls the wait usercall and checks the result. Returns true if event was
-    // returned, and false if WouldBlock/TimedOut was returned.
-    // If duration is None, it will use WAIT_NO.
-    fn wait_checked(event_mask: u64, duration: Option<Duration>) -> bool {
-        let timeout = duration.map_or(usercalls::raw::WAIT_NO, |duration| {
-            cmp::min((u64::MAX - 1) as u128, duration.as_nanos()) as u64
-        });
-        match usercalls::wait(event_mask, timeout) {
-            Ok(eventset) => {
-                if event_mask == 0 {
-                    rtabort!("expected usercalls::wait() to return Err, found Ok.");
-                }
-                // A matching event is one whose bits are equal to or a subset
-                // of `event_mask`.
-                rtassert!(eventset & !event_mask == 0);
-                true
-            }
-            Err(e) => {
-                rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock);
-                false
-            }
-        }
-    }
-
-    match wait_checked(event_mask, Some(duration)) {
-        false => return,                    // timed out
-        true if should_wake_up() => return, // woken up
-        true => {}                          // spurious event
-    }
-
-    // Drain all cached events.
-    // Note that `event_mask != 0` is implied if we get here.
-    loop {
-        match wait_checked(event_mask, None) {
-            false => break,                     // no more cached events
-            true if should_wake_up() => return, // woken up
-            true => {}                          // spurious event
-        }
-    }
-
-    // Continue waiting, but take note of time spent waiting so we don't wait
-    // forever. We intentionally don't call `Instant::now()` before this point
-    // to avoid the cost of the `insecure_time` usercall in case there are no
-    // spurious wakeups.
-
-    let start = Instant::now();
-    let mut remaining = duration;
-    loop {
-        match wait_checked(event_mask, Some(remaining)) {
-            false => return,                    // timed out
-            true if should_wake_up() => return, // woken up
-            true => {}                          // spurious event
-        }
-        remaining = match duration.checked_sub(start.elapsed()) {
-            Some(remaining) => remaining,
-            None => break,
-        }
-    }
-}
-
 // This enum is used as the storage for a bunch of types which can't actually
 // exist.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs
index 58b6f4346bc..5895f70436e 100644
--- a/src/libstd/sys/sgx/thread.rs
+++ b/src/libstd/sys/sgx/thread.rs
@@ -1,7 +1,6 @@
 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
 use crate::ffi::CStr;
 use crate::io;
-use crate::sys::usercall_wait_timeout;
 use crate::time::Duration;
 
 use super::abi::usercalls;
@@ -75,7 +74,7 @@ impl Thread {
     }
 
     pub fn sleep(dur: Duration) {
-        usercall_wait_timeout(0, dur, || true);
+        usercalls::wait_timeout(0, dur, || true);
     }
 
     pub fn join(self) {
diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs
index c8ccab2247a..070afa55f30 100644
--- a/src/libstd/sys/sgx/waitqueue.rs
+++ b/src/libstd/sys/sgx/waitqueue.rs
@@ -11,7 +11,6 @@
 //! The queue and associated wait state are stored in a `WaitVariable`.
 use crate::num::NonZeroUsize;
 use crate::ops::{Deref, DerefMut};
-use crate::sys::usercall_wait_timeout;
 use crate::time::Duration;
 
 use super::abi::thread;
@@ -176,7 +175,7 @@ impl WaitQueue {
             }));
             let entry_lock = lock.lock().queue.inner.push(&mut entry);
             before_wait();
-            usercall_wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake);
+            usercalls::wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake);
             // acquire the wait queue's lock first to avoid deadlock.
             let mut guard = lock.lock();
             let success = entry_lock.lock().wake;