Add support for clock_nanosleep
Also replace nanosleep implementation with clock_nanosleep
This commit is contained in:
parent
63db3e340c
commit
ffaccedf95
@ -141,7 +141,8 @@ enclave {
|
||||
void occlum_ocall_rdtsc([out] uint32_t* low, [out] uint32_t* high);
|
||||
void occlum_ocall_get_timerslack([out] int *timer_slack);
|
||||
|
||||
int occlum_ocall_nanosleep(
|
||||
int occlum_ocall_clock_nanosleep(
|
||||
clockid_t clockid, int flags,
|
||||
[in] const struct timespec* req,
|
||||
[out] struct timespec* rem
|
||||
) propagate_errno;
|
||||
|
@ -318,7 +318,7 @@ macro_rules! process_syscall_table_with_callback {
|
||||
(ClockSettime = 227) => handle_unsupported(),
|
||||
(ClockGettime = 228) => do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t),
|
||||
(ClockGetres = 229) => do_clock_getres(clockid: clockid_t, res_u: *mut timespec_t),
|
||||
(ClockNanosleep = 230) => handle_unsupported(),
|
||||
(ClockNanosleep = 230) => do_clock_nanosleep(clockid: clockid_t, flags: i32, request: *const timespec_t, remain: *mut timespec_t),
|
||||
(ExitGroup = 231) => do_exit_group(exit_status: i32, user_context: *mut CpuContext),
|
||||
(EpollWait = 232) => do_epoll_wait(epfd: c_int, events: *mut libc::epoll_event, maxevents: c_int, timeout: c_int),
|
||||
(EpollCtl = 233) => do_epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *const libc::epoll_event),
|
||||
@ -885,6 +885,27 @@ fn do_clock_getres(clockid: clockid_t, res_u: *mut timespec_t) -> Result<isize>
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn do_clock_nanosleep(
|
||||
clockid: clockid_t,
|
||||
flags: i32,
|
||||
req_u: *const timespec_t,
|
||||
rem_u: *mut timespec_t,
|
||||
) -> Result<isize> {
|
||||
let req = {
|
||||
check_ptr(req_u)?;
|
||||
timespec_t::from_raw_ptr(req_u)?
|
||||
};
|
||||
let rem = if !rem_u.is_null() {
|
||||
check_mut_ptr(rem_u)?;
|
||||
Some(unsafe { &mut *rem_u })
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let clockid = time::ClockID::from_raw(clockid)?;
|
||||
time::do_clock_nanosleep(clockid, flags, &req, rem)?;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
// TODO: handle remainder
|
||||
fn do_nanosleep(req_u: *const timespec_t, rem_u: *mut timespec_t) -> Result<isize> {
|
||||
let req = {
|
||||
|
@ -188,29 +188,63 @@ pub fn do_clock_getres(clockid: ClockID) -> Result<timespec_t> {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn do_nanosleep(req: ×pec_t, rem: Option<&mut timespec_t>) -> Result<()> {
|
||||
const TIMER_ABSTIME: i32 = 0x01;
|
||||
|
||||
pub fn do_clock_nanosleep(
|
||||
clockid: ClockID,
|
||||
flags: i32,
|
||||
req: ×pec_t,
|
||||
rem: Option<&mut timespec_t>,
|
||||
) -> Result<()> {
|
||||
extern "C" {
|
||||
fn occlum_ocall_nanosleep(
|
||||
fn occlum_ocall_clock_nanosleep(
|
||||
ret: *mut i32,
|
||||
clockid: clockid_t,
|
||||
flags: i32,
|
||||
req: *const timespec_t,
|
||||
rem: *mut timespec_t,
|
||||
) -> sgx_status_t;
|
||||
}
|
||||
unsafe {
|
||||
|
||||
let mut ret = 0;
|
||||
let mut u_rem: timespec_t = timespec_t { sec: 0, nsec: 0 };
|
||||
let sgx_status = occlum_ocall_nanosleep(&mut ret, req, &mut u_rem);
|
||||
match clockid {
|
||||
ClockID::CLOCK_REALTIME
|
||||
| ClockID::CLOCK_MONOTONIC
|
||||
| ClockID::CLOCK_BOOTTIME
|
||||
| ClockID::CLOCK_PROCESS_CPUTIME_ID => {}
|
||||
ClockID::CLOCK_THREAD_CPUTIME_ID => {
|
||||
return_errno!(EINVAL, "CLOCK_THREAD_CPUTIME_ID is not a permitted value");
|
||||
}
|
||||
_ => {
|
||||
return_errno!(EOPNOTSUPP, "does not support sleeping against this clockid");
|
||||
}
|
||||
}
|
||||
let sgx_status = unsafe {
|
||||
occlum_ocall_clock_nanosleep(&mut ret, clockid as clockid_t, flags, req, &mut u_rem)
|
||||
};
|
||||
assert!(sgx_status == sgx_status_t::SGX_SUCCESS);
|
||||
assert!(ret == 0 || libc::errno() == Errno::EINTR as i32);
|
||||
assert!(ret == 0 || ret == Errno::EINTR as i32);
|
||||
if ret != 0 {
|
||||
assert!(u_rem.as_duration() <= req.as_duration() + (*TIMERSLACK).to_duration());
|
||||
// rem is only valid if TIMER_ABSTIME flag is not set
|
||||
if flags != TIMER_ABSTIME {
|
||||
if let Some(rem) = rem {
|
||||
*rem = u_rem;
|
||||
}
|
||||
}
|
||||
return_errno!(EINTR, "sleep interrupted");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn do_nanosleep(req: ×pec_t, rem: Option<&mut timespec_t>) -> Result<()> {
|
||||
// POSIX.1 specifies that nanosleep() should measure time against
|
||||
// the CLOCK_REALTIME clock. However, Linux measures the time using
|
||||
// the CLOCK_MONOTONIC clock.
|
||||
// Here we follow the POSIX.1
|
||||
let clock_id = ClockID::CLOCK_REALTIME;
|
||||
return do_clock_nanosleep(clock_id, 0, req, rem);
|
||||
}
|
||||
|
||||
pub fn do_thread_getcpuclock() -> Result<timespec_t> {
|
||||
|
@ -16,8 +16,9 @@ void occlum_ocall_clock_getres(int clockid, struct timespec *res) {
|
||||
clock_getres(clockid, res);
|
||||
}
|
||||
|
||||
int occlum_ocall_nanosleep(const struct timespec *req, struct timespec *rem) {
|
||||
return nanosleep(req, rem);
|
||||
int occlum_ocall_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
return clock_nanosleep(clockid, flags, req, rem);
|
||||
}
|
||||
|
||||
int occlum_ocall_thread_getcpuclock(struct timespec *tp) {
|
||||
|
Loading…
Reference in New Issue
Block a user