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_rdtsc([out] uint32_t* low, [out] uint32_t* high);
|
||||||
void occlum_ocall_get_timerslack([out] int *timer_slack);
|
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,
|
[in] const struct timespec* req,
|
||||||
[out] struct timespec* rem
|
[out] struct timespec* rem
|
||||||
) propagate_errno;
|
) propagate_errno;
|
||||||
|
@ -318,7 +318,7 @@ macro_rules! process_syscall_table_with_callback {
|
|||||||
(ClockSettime = 227) => handle_unsupported(),
|
(ClockSettime = 227) => handle_unsupported(),
|
||||||
(ClockGettime = 228) => do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t),
|
(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),
|
(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),
|
(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),
|
(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),
|
(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)
|
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
|
// TODO: handle remainder
|
||||||
fn do_nanosleep(req_u: *const timespec_t, rem_u: *mut timespec_t) -> Result<isize> {
|
fn do_nanosleep(req_u: *const timespec_t, rem_u: *mut timespec_t) -> Result<isize> {
|
||||||
let req = {
|
let req = {
|
||||||
|
@ -188,29 +188,63 @@ pub fn do_clock_getres(clockid: ClockID) -> Result<timespec_t> {
|
|||||||
Ok(res)
|
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" {
|
extern "C" {
|
||||||
fn occlum_ocall_nanosleep(
|
fn occlum_ocall_clock_nanosleep(
|
||||||
ret: *mut i32,
|
ret: *mut i32,
|
||||||
|
clockid: clockid_t,
|
||||||
|
flags: i32,
|
||||||
req: *const timespec_t,
|
req: *const timespec_t,
|
||||||
rem: *mut timespec_t,
|
rem: *mut timespec_t,
|
||||||
) -> sgx_status_t;
|
) -> sgx_status_t;
|
||||||
}
|
}
|
||||||
unsafe {
|
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
let mut u_rem: timespec_t = timespec_t { sec: 0, nsec: 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 {
|
||||||
assert!(sgx_status == sgx_status_t::SGX_SUCCESS);
|
ClockID::CLOCK_REALTIME
|
||||||
assert!(ret == 0 || libc::errno() == Errno::EINTR as i32);
|
| ClockID::CLOCK_MONOTONIC
|
||||||
if ret != 0 {
|
| ClockID::CLOCK_BOOTTIME
|
||||||
assert!(u_rem.as_duration() <= req.as_duration() + (*TIMERSLACK).to_duration());
|
| 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 || 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 {
|
if let Some(rem) = rem {
|
||||||
*rem = u_rem;
|
*rem = u_rem;
|
||||||
}
|
}
|
||||||
return_errno!(EINTR, "sleep interrupted");
|
|
||||||
}
|
}
|
||||||
|
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> {
|
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);
|
clock_getres(clockid, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
int occlum_ocall_nanosleep(const struct timespec *req, struct timespec *rem) {
|
int occlum_ocall_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *req,
|
||||||
return nanosleep(req, rem);
|
struct timespec *rem) {
|
||||||
|
return clock_nanosleep(clockid, flags, req, rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int occlum_ocall_thread_getcpuclock(struct timespec *tp) {
|
int occlum_ocall_thread_getcpuclock(struct timespec *tp) {
|
||||||
|
Loading…
Reference in New Issue
Block a user