Add clock_getres syscall
This commit is contained in:
parent
70d3991ff5
commit
c8e3e0ffc6
@ -97,6 +97,7 @@ enclave {
|
||||
|
||||
void occlum_ocall_gettimeofday([out] struct timeval* tv);
|
||||
void occlum_ocall_clock_gettime(clockid_t clockid, [out] struct timespec* ts);
|
||||
void occlum_ocall_clock_getres(clockid_t clockid, [out] struct timespec* res);
|
||||
void occlum_ocall_rdtsc([out] uint32_t* low, [out] uint32_t* high);
|
||||
|
||||
void occlum_ocall_nanosleep([in] const struct timespec* req);
|
||||
|
@ -306,7 +306,7 @@ macro_rules! process_syscall_table_with_callback {
|
||||
(TimerDelete = 226) => handle_unsupported(),
|
||||
(ClockSettime = 227) => handle_unsupported(),
|
||||
(ClockGettime = 228) => do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t),
|
||||
(ClockGetres = 229) => handle_unsupported(),
|
||||
(ClockGetres = 229) => do_clock_getres(clockid: clockid_t, res_u: *mut timespec_t),
|
||||
(ClockNanosleep = 230) => handle_unsupported(),
|
||||
(ExitGroup = 231) => do_exit_group(exit_status: i32),
|
||||
(EpollWait = 232) => do_epoll_wait(epfd: c_int, events: *mut libc::epoll_event, maxevents: c_int, timeout: c_int),
|
||||
@ -775,6 +775,19 @@ fn do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t) -> Result<isize>
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn do_clock_getres(clockid: clockid_t, res_u: *mut timespec_t) -> Result<isize> {
|
||||
if res_u.is_null() {
|
||||
return Ok(0);
|
||||
}
|
||||
check_mut_ptr(res_u)?;
|
||||
let clockid = time::ClockID::from_raw(clockid)?;
|
||||
let res = time::do_clock_getres(clockid)?;
|
||||
unsafe {
|
||||
*res_u = res;
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
// TODO: handle remainder
|
||||
fn do_nanosleep(req_u: *const timespec_t, rem_u: *mut timespec_t) -> Result<isize> {
|
||||
check_ptr(req_u)?;
|
||||
|
@ -137,6 +137,28 @@ pub fn do_clock_gettime(clockid: ClockID) -> Result<timespec_t> {
|
||||
Ok(tv)
|
||||
}
|
||||
|
||||
pub fn do_clock_getres(clockid: ClockID) -> Result<timespec_t> {
|
||||
extern "C" {
|
||||
fn occlum_ocall_clock_getres(clockid: clockid_t, res: *mut timespec_t) -> sgx_status_t;
|
||||
}
|
||||
|
||||
let mut res: timespec_t = Default::default();
|
||||
unsafe {
|
||||
occlum_ocall_clock_getres(clockid as clockid_t, &mut res as *mut timespec_t);
|
||||
}
|
||||
let validate_resolution = |res: ×pec_t| -> Result<()> {
|
||||
// The resolution can be ranged from 1 nanosecond to a few milliseconds
|
||||
if res.sec == 0 && res.nsec > 0 && res.nsec < 1_000_000_000 {
|
||||
Ok(())
|
||||
} else {
|
||||
return_errno!(EINVAL, "invalid value for resolution");
|
||||
}
|
||||
};
|
||||
// do sanity check
|
||||
validate_resolution(&res).expect("ocall returned invalid resolution");
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn do_nanosleep(req: ×pec_t) -> Result<()> {
|
||||
extern "C" {
|
||||
fn occlum_ocall_nanosleep(req: *const timespec_t) -> sgx_status_t;
|
||||
|
@ -10,6 +10,10 @@ void occlum_ocall_clock_gettime(int clockid, struct timespec *tp) {
|
||||
clock_gettime(clockid, tp);
|
||||
}
|
||||
|
||||
void occlum_ocall_clock_getres(int clockid, struct timespec *res) {
|
||||
clock_getres(clockid, res);
|
||||
}
|
||||
|
||||
void occlum_ocall_nanosleep(const struct timespec *req) {
|
||||
nanosleep(req, NULL);
|
||||
}
|
||||
|
@ -29,6 +29,27 @@ int test_clock_gettime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test cases for clock_getres
|
||||
// ============================================================================
|
||||
|
||||
int test_clock_getres() {
|
||||
struct timespec res;
|
||||
if (clock_getres(CLOCK_REALTIME, &res)) {
|
||||
THROW_ERROR("clock_getres(CLOCK_REALTIME, ...) failed");
|
||||
}
|
||||
if (clock_getres(CLOCK_MONOTONIC, &res)) {
|
||||
THROW_ERROR("clock_getres(CLOCK_MONOTONIC, ...) failed");
|
||||
}
|
||||
if (clock_getres(CLOCK_MONOTONIC_COARSE, &res)) {
|
||||
THROW_ERROR("clock_getres(CLOCK_MONOTONIC_COARSE, ...) failed");
|
||||
}
|
||||
if (clock_getres(CLOCK_REALTIME, NULL)) {
|
||||
THROW_ERROR("clock_getres(CLOCK_REALTIME, NULL) failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test suite
|
||||
// ============================================================================
|
||||
@ -36,6 +57,7 @@ int test_clock_gettime() {
|
||||
static test_case_t test_cases[] = {
|
||||
TEST_CASE(test_gettimeofday),
|
||||
TEST_CASE(test_clock_gettime),
|
||||
TEST_CASE(test_clock_getres),
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
Loading…
Reference in New Issue
Block a user