Skip to content

Commit 85c25ae

Browse files
committed
Move usercall_wait_timeout to abi::usercalls::wait_timeout
1 parent 1466598 commit 85c25ae

File tree

4 files changed

+74
-82
lines changed

4 files changed

+74
-82
lines changed

src/libstd/sys/sgx/abi/usercalls/mod.rs

+72-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::cmp;
22
use crate::convert::TryFrom;
3-
use crate::io::{Error as IoError, IoSlice, IoSliceMut, Result as IoResult};
3+
use crate::io::{Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult};
44
use crate::sys::rand::rdrand64;
5-
use crate::time::Duration;
5+
use crate::time::{Duration, Instant};
66

77
pub(crate) mod alloc;
88
#[macro_use]
@@ -169,6 +169,76 @@ pub fn wait(event_mask: u64, mut timeout: u64) -> IoResult<u64> {
169169
unsafe { raw::wait(event_mask, timeout).from_sgx_result() }
170170
}
171171

172+
/// This function makes an effort to wait for a non-spurious event at least as
173+
/// long as `duration`. Note that in general there is no guarantee about accuracy
174+
/// of time and timeouts in SGX model. The enclave runner serving usercalls may
175+
/// lie about current time and/or ignore timeout values.
176+
///
177+
/// Once the event is observed, `should_wake_up` will be used to determine
178+
/// whether or not the event was spurious.
179+
#[unstable(feature = "sgx_platform", issue = "56975")]
180+
pub fn wait_timeout<F>(event_mask: u64, duration: Duration, should_wake_up: F)
181+
where
182+
F: Fn() -> bool,
183+
{
184+
// Calls the wait usercall and checks the result. Returns true if event was
185+
// returned, and false if WouldBlock/TimedOut was returned.
186+
// If duration is None, it will use WAIT_NO.
187+
fn wait_checked(event_mask: u64, duration: Option<Duration>) -> bool {
188+
let timeout = duration.map_or(raw::WAIT_NO, |duration| {
189+
cmp::min((u64::MAX - 1) as u128, duration.as_nanos()) as u64
190+
});
191+
match wait(event_mask, timeout) {
192+
Ok(eventset) => {
193+
if event_mask == 0 {
194+
rtabort!("expected wait() to return Err, found Ok.");
195+
}
196+
rtassert!(eventset != 0 && eventset & !event_mask == 0);
197+
true
198+
}
199+
Err(e) => {
200+
rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock);
201+
false
202+
}
203+
}
204+
}
205+
206+
match wait_checked(event_mask, Some(duration)) {
207+
false => return, // timed out
208+
true if should_wake_up() => return, // woken up
209+
true => {} // spurious event
210+
}
211+
212+
// Drain all cached events.
213+
// Note that `event_mask != 0` is implied if we get here.
214+
loop {
215+
match wait_checked(event_mask, None) {
216+
false => break, // no more cached events
217+
true if should_wake_up() => return, // woken up
218+
true => {} // spurious event
219+
}
220+
}
221+
222+
// Continue waiting, but take note of time spent waiting so we don't wait
223+
// forever. We intentionally don't call `Instant::now()` before this point
224+
// to avoid the cost of the `insecure_time` usercall in case there are no
225+
// spurious wakeups.
226+
227+
let start = Instant::now();
228+
let mut remaining = duration;
229+
loop {
230+
match wait_checked(event_mask, Some(remaining)) {
231+
false => return, // timed out
232+
true if should_wake_up() => return, // woken up
233+
true => {} // spurious event
234+
}
235+
remaining = match duration.checked_sub(start.elapsed()) {
236+
Some(remaining) => remaining,
237+
None => break,
238+
}
239+
}
240+
}
241+
172242
/// Usercall `send`. See the ABI documentation for more information.
173243
#[unstable(feature = "sgx_platform", issue = "56975")]
174244
pub fn send(event_set: u64, tcs: Option<Tcs>) -> IoResult<()> {

src/libstd/sys/sgx/mod.rs

-76
Original file line numberDiff line numberDiff line change
@@ -110,82 +110,6 @@ pub fn decode_error_kind(code: i32) -> ErrorKind {
110110
}
111111
}
112112

113-
// This function makes an effort to wait for a non-spurious event at least as
114-
// long as `duration`. Note that in general there is no guarantee about accuracy
115-
// of time and timeouts in SGX model. The enclave runner serving usercalls may
116-
// lie about current time and/or ignore timeout values.
117-
//
118-
// Once the event is observed, `should_wake_up` will be used to determine
119-
// whether or not the event was spurious.
120-
pub fn usercall_wait_timeout<F>(event_mask: u64, duration: crate::time::Duration, should_wake_up: F)
121-
where
122-
F: Fn() -> bool,
123-
{
124-
use self::abi::usercalls;
125-
use crate::cmp;
126-
use crate::io::ErrorKind;
127-
use crate::time::{Duration, Instant};
128-
129-
// Calls the wait usercall and checks the result. Returns true if event was
130-
// returned, and false if WouldBlock/TimedOut was returned.
131-
// If duration is None, it will use WAIT_NO.
132-
fn wait_checked(event_mask: u64, duration: Option<Duration>) -> bool {
133-
let timeout = duration.map_or(usercalls::raw::WAIT_NO, |duration| {
134-
cmp::min((u64::MAX - 1) as u128, duration.as_nanos()) as u64
135-
});
136-
match usercalls::wait(event_mask, timeout) {
137-
Ok(eventset) => {
138-
if event_mask == 0 {
139-
rtabort!("expected usercalls::wait() to return Err, found Ok.");
140-
}
141-
// A matching event is one whose bits are equal to or a subset
142-
// of `event_mask`.
143-
rtassert!(eventset & !event_mask == 0);
144-
true
145-
}
146-
Err(e) => {
147-
rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock);
148-
false
149-
}
150-
}
151-
}
152-
153-
match wait_checked(event_mask, Some(duration)) {
154-
false => return, // timed out
155-
true if should_wake_up() => return, // woken up
156-
true => {} // spurious event
157-
}
158-
159-
// Drain all cached events.
160-
// Note that `event_mask != 0` is implied if we get here.
161-
loop {
162-
match wait_checked(event_mask, None) {
163-
false => break, // no more cached events
164-
true if should_wake_up() => return, // woken up
165-
true => {} // spurious event
166-
}
167-
}
168-
169-
// Continue waiting, but take note of time spent waiting so we don't wait
170-
// forever. We intentionally don't call `Instant::now()` before this point
171-
// to avoid the cost of the `insecure_time` usercall in case there are no
172-
// spurious wakeups.
173-
174-
let start = Instant::now();
175-
let mut remaining = duration;
176-
loop {
177-
match wait_checked(event_mask, Some(remaining)) {
178-
false => return, // timed out
179-
true if should_wake_up() => return, // woken up
180-
true => {} // spurious event
181-
}
182-
remaining = match duration.checked_sub(start.elapsed()) {
183-
Some(remaining) => remaining,
184-
None => break,
185-
}
186-
}
187-
}
188-
189113
// This enum is used as the storage for a bunch of types which can't actually
190114
// exist.
191115
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]

src/libstd/sys/sgx/thread.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![cfg_attr(test, allow(dead_code))] // why is this necessary?
22
use crate::ffi::CStr;
33
use crate::io;
4-
use crate::sys::usercall_wait_timeout;
54
use crate::time::Duration;
65

76
use super::abi::usercalls;
@@ -75,7 +74,7 @@ impl Thread {
7574
}
7675

7776
pub fn sleep(dur: Duration) {
78-
usercall_wait_timeout(0, dur, || true);
77+
usercalls::wait_timeout(0, dur, || true);
7978
}
8079

8180
pub fn join(self) {

src/libstd/sys/sgx/waitqueue.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//! The queue and associated wait state are stored in a `WaitVariable`.
1212
use crate::num::NonZeroUsize;
1313
use crate::ops::{Deref, DerefMut};
14-
use crate::sys::usercall_wait_timeout;
1514
use crate::time::Duration;
1615

1716
use super::abi::thread;
@@ -176,7 +175,7 @@ impl WaitQueue {
176175
}));
177176
let entry_lock = lock.lock().queue.inner.push(&mut entry);
178177
before_wait();
179-
usercall_wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake);
178+
usercalls::wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake);
180179
// acquire the wait queue's lock first to avoid deadlock.
181180
let mut guard = lock.lock();
182181
let success = entry_lock.lock().wake;

0 commit comments

Comments
 (0)