From ab89421f960516da3db5a8f45f03de5f0b3168db Mon Sep 17 00:00:00 2001 From: LI Qing Date: Mon, 18 Nov 2019 02:20:44 +0000 Subject: [PATCH] Add sched_yield syscall --- src/Enclave.edl | 1 + src/libos/src/process/mod.rs | 2 +- src/libos/src/process/sched.rs | 8 ++++++++ src/libos/src/syscall/mod.rs | 8 ++++++++ src/pal/pal.c | 6 ++++++ test/sched/main.c | 13 +++++++++++++ 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Enclave.edl b/src/Enclave.edl index 5e9ff290..1d7545ac 100644 --- a/src/Enclave.edl +++ b/src/Enclave.edl @@ -21,6 +21,7 @@ enclave { void ocall_clock_gettime(int clockid, [out] long* sec, [out] long* ns); void ocall_nanosleep(long sec, long nsec); void ocall_sync(void); + void ocall_sched_yield(void); int ocall_sched_getaffinity([out] int *error, int pid, size_t cpusize, [out, size=cpusize] unsigned char* buf); int ocall_sched_setaffinity([out] int *error, int pid, size_t cpusize, [in, size=cpusize] const unsigned char* buf); }; diff --git a/src/libos/src/process/mod.rs b/src/libos/src/process/mod.rs index 393fdf61..5f5a0e77 100644 --- a/src/libos/src/process/mod.rs +++ b/src/libos/src/process/mod.rs @@ -3,7 +3,7 @@ pub use self::exit::{do_exit, do_wait4, ChildProcessFilter}; pub use self::futex::{futex_op_and_flags_from_u32, futex_wait, futex_wake, FutexFlags, FutexOp}; pub use self::process::{Status, IDLE_PROCESS}; pub use self::process_table::get; -pub use self::sched::{do_sched_getaffinity, do_sched_setaffinity, CpuSet}; +pub use self::sched::{do_sched_getaffinity, do_sched_setaffinity, do_sched_yield, CpuSet}; pub use self::spawn::{do_spawn, ElfFile, FileAction, ProgramHeaderExt}; pub use self::task::{current_pid, get_current, run_task}; pub use self::thread::{do_clone, do_set_tid_address, CloneFlags, ThreadGroup}; diff --git a/src/libos/src/process/sched.rs b/src/libos/src/process/sched.rs index 8acc6bf3..dbbf8986 100644 --- a/src/libos/src/process/sched.rs +++ b/src/libos/src/process/sched.rs @@ -15,6 +15,7 @@ extern "C" { cpusetsize: size_t, mask: *const c_uchar, ) -> sgx_status_t; + fn ocall_sched_yield() -> sgx_status_t; } pub struct CpuSet { @@ -122,3 +123,10 @@ pub fn do_sched_setaffinity(pid: pid_t, cpu_set: &CpuSet) -> Result { } Ok(ret) } + +pub fn do_sched_yield() { + unsafe { + let status = ocall_sched_yield(); + assert!(status == sgx_status_t::SGX_SUCCESS); + } +} diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs index bc1cdea9..15dd831e 100644 --- a/src/libos/src/syscall/mod.rs +++ b/src/libos/src/syscall/mod.rs @@ -182,6 +182,9 @@ pub extern "C" fn dispatch_syscall( ), SYS_ARCH_PRCTL => do_arch_prctl(arg0 as u32, arg1 as *mut usize), SYS_SET_TID_ADDRESS => do_set_tid_address(arg0 as *mut pid_t), + + // sched + SYS_SCHED_YIELD => do_sched_yield(), SYS_SCHED_GETAFFINITY => { do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar) } @@ -991,6 +994,11 @@ fn do_set_tid_address(tidptr: *mut pid_t) -> Result { process::do_set_tid_address(tidptr).map(|tid| tid as isize) } +fn do_sched_yield() -> Result { + process::do_sched_yield(); + Ok(0) +} + fn do_sched_getaffinity(pid: pid_t, cpusize: size_t, buf: *mut c_uchar) -> Result { // Construct safe Rust types let mut buf_slice = { diff --git a/src/pal/pal.c b/src/pal/pal.c index 1ffb7cd9..5634bcf5 100644 --- a/src/pal/pal.c +++ b/src/pal/pal.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -286,6 +287,11 @@ int ocall_sched_setaffinity(int* error, int pid, size_t cpusize, const unsigned return ret; } +/* In the Linux implementation, sched_yield() always succeeds */ +void ocall_sched_yield(void) { + sched_yield(); +} + void ocall_sync(void) { sync(); } diff --git a/test/sched/main.c b/test/sched/main.c index 16f50a0e..84be07f3 100644 --- a/test/sched/main.c +++ b/test/sched/main.c @@ -154,6 +154,18 @@ static int test_sched_setaffinity_with_null_buffer() { return 0; } +// ============================================================================ +// Test cases for sched_yield +// ============================================================================ + +static int test_sched_yield() { + // In the Linux implementation, sched_yield() always succeeds. + if (sched_yield() < 0) { + THROW_ERROR("check sched yield fail"); + } + return 0; +} + // ============================================================================ // Test suite main // ============================================================================ @@ -168,6 +180,7 @@ static test_case_t test_cases[] = { TEST_CASE(test_sched_setaffinity_with_zero_cpusetsize), TEST_CASE(test_sched_getaffinity_with_null_buffer), TEST_CASE(test_sched_setaffinity_with_null_buffer), + TEST_CASE(test_sched_yield), }; int main() {