Add clock_gettimeofday
This commit is contained in:
parent
c096e7d0b9
commit
e1e46c9935
@ -17,7 +17,8 @@ enclave {
|
||||
untrusted {
|
||||
void ocall_print_string([in, string] const char* msg);
|
||||
int ocall_run_new_task(void);
|
||||
void ocall_gettimeofday([out] long* seconds, [out] long* microseconds);
|
||||
void ocall_gettimeofday([out] long* sec, [out] long* us);
|
||||
void ocall_clock_gettime(int clockid, [out] long* sec, [out] long* ns);
|
||||
void ocall_sync(void);
|
||||
};
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ use prelude::*;
|
||||
use process::{pid_t, ChildProcessFilter, CloneFlags, FileAction, FutexFlags, FutexOp};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ptr;
|
||||
use time::timeval_t;
|
||||
use time::{timeval_t, clockid_t, timespec_t};
|
||||
use util::mem_util::from_user::*;
|
||||
use vm::{VMPerms, MMapFlags};
|
||||
use {fs, process, std, vm};
|
||||
@ -203,6 +203,7 @@ pub extern "C" fn dispatch_syscall(
|
||||
SYS_DUP3 => do_dup3(arg0 as FileDesc, arg1 as FileDesc, arg2 as u32),
|
||||
|
||||
SYS_GETTIMEOFDAY => do_gettimeofday(arg0 as *mut timeval_t),
|
||||
SYS_CLOCK_GETTIME => do_clock_gettime(arg0 as clockid_t, arg1 as *mut timespec_t),
|
||||
|
||||
SYS_UNAME => do_uname(arg0 as *mut utsname_t),
|
||||
|
||||
@ -790,6 +791,17 @@ fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<isize, Error> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t) -> Result<isize, Error> {
|
||||
check_mut_ptr(ts_u)?;
|
||||
let clockid = time::ClockID::from_raw(clockid)?;
|
||||
let ts = time::do_clock_gettime(clockid)?;
|
||||
unsafe {
|
||||
*ts_u = ts;
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
||||
// FIXME: use this
|
||||
const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void;
|
||||
|
||||
|
@ -11,6 +11,7 @@ pub type suseconds_t = i64;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct timeval_t {
|
||||
sec: time_t,
|
||||
usec: suseconds_t,
|
||||
@ -34,6 +35,64 @@ extern "C" {
|
||||
fn ocall_gettimeofday(sec: *mut time_t, usec: *mut suseconds_t) -> sgx_status_t;
|
||||
}
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct timespec_t {
|
||||
sec: time_t,
|
||||
nsec: i64,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type clockid_t = i32;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum ClockID {
|
||||
CLOCK_REALTIME = 0,
|
||||
CLOCK_MONOTONIC = 1,
|
||||
CLOCK_PROCESS_CPUTIME_ID = 2,
|
||||
CLOCK_THREAD_CPUTIME_ID = 3,
|
||||
CLOCK_MONOTONIC_RAW = 4,
|
||||
CLOCK_REALTIME_COARSE = 5,
|
||||
CLOCK_MONOTONIC_COARSE = 6,
|
||||
CLOCK_BOOTTIME = 7,
|
||||
}
|
||||
|
||||
impl ClockID {
|
||||
#[deny(unreachable_patterns)]
|
||||
pub fn from_raw(clockid: clockid_t) -> Result<ClockID, Error> {
|
||||
Ok(match clockid as i32 {
|
||||
0 => ClockID::CLOCK_REALTIME,
|
||||
1 => ClockID::CLOCK_MONOTONIC,
|
||||
2 => ClockID::CLOCK_PROCESS_CPUTIME_ID,
|
||||
3 => ClockID::CLOCK_THREAD_CPUTIME_ID,
|
||||
4 => ClockID::CLOCK_MONOTONIC_RAW,
|
||||
5 => ClockID::CLOCK_REALTIME_COARSE,
|
||||
6 => ClockID::CLOCK_MONOTONIC_COARSE,
|
||||
7 => ClockID::CLOCK_BOOTTIME,
|
||||
_ => return errno!(EINVAL, "invalid command"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn do_clock_gettime(clockid: ClockID) -> Result<timespec_t, Error> {
|
||||
let mut sec = 0;
|
||||
let mut nsec = 0;
|
||||
unsafe {
|
||||
ocall_clock_gettime(clockid as clockid_t, &mut sec as *mut time_t, &mut nsec as *mut i64);
|
||||
}
|
||||
Ok(timespec_t { sec, nsec })
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn ocall_clock_gettime(clockid: clockid_t, sec: *mut time_t, ns: *mut i64) -> sgx_status_t;
|
||||
}
|
||||
|
||||
|
||||
// For SEFS
|
||||
|
||||
pub struct OcclumTimeProvider;
|
||||
|
||||
impl TimeProvider for OcclumTimeProvider {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#define MAX_PATH FILENAME_MAX
|
||||
|
||||
@ -205,6 +206,13 @@ void ocall_gettimeofday(long* seconds, long* microseconds) {
|
||||
*microseconds = tv.tv_usec;
|
||||
}
|
||||
|
||||
void ocall_clock_gettime(int clockid, time_t* sec, long* ns) {
|
||||
struct timespec ts;
|
||||
clock_gettime(clockid, &ts);
|
||||
*sec = ts.tv_sec;
|
||||
*ns = ts.tv_nsec;
|
||||
}
|
||||
|
||||
void ocall_sync(void) {
|
||||
sync();
|
||||
}
|
||||
|
40
test/include/test.h
Normal file
40
test/include/test.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef __TEST_H
|
||||
#define __TEST_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define _STR(x) #x
|
||||
#define STR(x) _STR(x)
|
||||
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
|
||||
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
|
||||
typedef int(*test_case_func_t)(void);
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
test_case_func_t func;
|
||||
} test_case_t;
|
||||
|
||||
#define TEST_CASE(name) { STR(name), name }
|
||||
|
||||
#define throw_error(msg) while(1) { \
|
||||
printf("\t\tERROR: %s in func %s at line %d of file %s\n", \
|
||||
(msg), __func__, __LINE__, __FILE__); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
int test_suite_run(test_case_t* test_cases, int num_test_cases) {
|
||||
for (int ti = 0; ti < num_test_cases; ti++) {
|
||||
test_case_t* tc = &test_cases[ti];
|
||||
if (tc->func() < 0) {
|
||||
printf(" func %s - [ERR]\n", tc->name);
|
||||
return -1;
|
||||
}
|
||||
printf(" func %s - [OK]\n", tc->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __TEST_H */
|
@ -7,6 +7,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "test.h"
|
||||
|
||||
// ============================================================================
|
||||
// Helper macros
|
||||
@ -16,23 +17,9 @@
|
||||
#define MB (1024 * 1024UL)
|
||||
#define PAGE_SIZE (4 * KB)
|
||||
|
||||
#define _STR(x) #x
|
||||
#define STR(x) _STR(x)
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
#define ALIGN_DOWN(x, a) ((x) & ~(a-1)) // a must be a power of two
|
||||
#define ALIGN_UP(x, a) ALIGN_DOWN((x+(a-1)), (a))
|
||||
|
||||
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
|
||||
|
||||
#define throw_error(msg) while(1) { \
|
||||
printf("ERROR: %s in func %s at line %d of file %s\n", \
|
||||
(msg), __func__, __LINE__, __FILE__); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
#define MAX_MMAP_USED_MEMORY (4 * MB)
|
||||
|
||||
// ============================================================================
|
||||
@ -632,14 +619,6 @@ int test_munmap_with_non_page_aligned_len() {
|
||||
// Test suite main
|
||||
// ============================================================================
|
||||
|
||||
typedef int(*test_case_func_t)(void);
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
test_case_func_t func;
|
||||
} test_case_t;
|
||||
|
||||
#define TEST_CASE(name) { STR(name), name }
|
||||
static test_case_t test_cases[] = {
|
||||
TEST_CASE(test_anonymous_mmap),
|
||||
TEST_CASE(test_anonymous_mmap_randomly),
|
||||
@ -669,13 +648,5 @@ int main() {
|
||||
throw_error("test_suite_init failed");
|
||||
}
|
||||
|
||||
for (int ti = 0; ti < ARRAY_SIZE(test_cases); ti++) {
|
||||
test_case_t* tc = &test_cases[ti];
|
||||
if (tc->func() < 0) {
|
||||
printf(" func %s - [ERR]\n", tc->name);
|
||||
return -1;
|
||||
}
|
||||
printf(" func %s - [OK]\n", tc->name);
|
||||
}
|
||||
return 0;
|
||||
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ READELF_FILE := bin.readelf
|
||||
CLANG_BIN_PATH := $(shell clang -print-prog-name=clang)
|
||||
LLVM_PATH := $(abspath $(dir $(CLANG_BIN_PATH))../)
|
||||
|
||||
C_FLAGS = -Wall -O2 -fPIC $(EXTRA_C_FLAGS)
|
||||
C_FLAGS = -Wall -I../include -O2 -fPIC $(EXTRA_C_FLAGS)
|
||||
C_FLAGS += -Xclang -load -Xclang $(LLVM_PATH)/lib/LLVMMDSFIIRInserter.so
|
||||
LINK_FLAGS = $(C_FLAGS) -pie -locclum_stub $(EXTRA_LINK_FLAGS)
|
||||
|
||||
|
@ -1,9 +1,43 @@
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "test.h"
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
// ============================================================================
|
||||
// Test cases for gettimeofday
|
||||
// ============================================================================
|
||||
|
||||
int test_gettimeofday() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
printf("sec = %lu, usec = %lu\n", tv.tv_sec, tv.tv_usec);
|
||||
if (gettimeofday(&tv, NULL)) {
|
||||
throw_error("gettimeofday failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test cases for clock_gettime
|
||||
// ============================================================================
|
||||
|
||||
int test_clock_gettime() {
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts)) {
|
||||
throw_error("clock_gettime(CLOCK_REALTIME, ...) failed");
|
||||
}
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
|
||||
throw_error("clock_gettime(CLOCK_MONOTONIC, ...) failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test suite
|
||||
// ============================================================================
|
||||
|
||||
static test_case_t test_cases[] = {
|
||||
TEST_CASE(test_gettimeofday),
|
||||
TEST_CASE(test_clock_gettime),
|
||||
};
|
||||
|
||||
int main() {
|
||||
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user