Add sched_yield syscall

This commit is contained in:
LI Qing 2019-11-18 02:20:44 +00:00 committed by Tate, Hongliang Tian
parent 1304f5388d
commit ab89421f96
6 changed files with 37 additions and 1 deletions

@ -21,6 +21,7 @@ enclave {
void ocall_clock_gettime(int clockid, [out] long* sec, [out] long* ns); void ocall_clock_gettime(int clockid, [out] long* sec, [out] long* ns);
void ocall_nanosleep(long sec, long nsec); void ocall_nanosleep(long sec, long nsec);
void ocall_sync(void); 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_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); int ocall_sched_setaffinity([out] int *error, int pid, size_t cpusize, [in, size=cpusize] const unsigned char* buf);
}; };

@ -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::futex::{futex_op_and_flags_from_u32, futex_wait, futex_wake, FutexFlags, FutexOp};
pub use self::process::{Status, IDLE_PROCESS}; pub use self::process::{Status, IDLE_PROCESS};
pub use self::process_table::get; 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::spawn::{do_spawn, ElfFile, FileAction, ProgramHeaderExt};
pub use self::task::{current_pid, get_current, run_task}; pub use self::task::{current_pid, get_current, run_task};
pub use self::thread::{do_clone, do_set_tid_address, CloneFlags, ThreadGroup}; pub use self::thread::{do_clone, do_set_tid_address, CloneFlags, ThreadGroup};

@ -15,6 +15,7 @@ extern "C" {
cpusetsize: size_t, cpusetsize: size_t,
mask: *const c_uchar, mask: *const c_uchar,
) -> sgx_status_t; ) -> sgx_status_t;
fn ocall_sched_yield() -> sgx_status_t;
} }
pub struct CpuSet { pub struct CpuSet {
@ -122,3 +123,10 @@ pub fn do_sched_setaffinity(pid: pid_t, cpu_set: &CpuSet) -> Result<i32> {
} }
Ok(ret) Ok(ret)
} }
pub fn do_sched_yield() {
unsafe {
let status = ocall_sched_yield();
assert!(status == sgx_status_t::SGX_SUCCESS);
}
}

@ -182,6 +182,9 @@ pub extern "C" fn dispatch_syscall(
), ),
SYS_ARCH_PRCTL => do_arch_prctl(arg0 as u32, arg1 as *mut usize), 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), SYS_SET_TID_ADDRESS => do_set_tid_address(arg0 as *mut pid_t),
// sched
SYS_SCHED_YIELD => do_sched_yield(),
SYS_SCHED_GETAFFINITY => { SYS_SCHED_GETAFFINITY => {
do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar) 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<isize> {
process::do_set_tid_address(tidptr).map(|tid| tid as isize) process::do_set_tid_address(tidptr).map(|tid| tid as isize)
} }
fn do_sched_yield() -> Result<isize> {
process::do_sched_yield();
Ok(0)
}
fn do_sched_getaffinity(pid: pid_t, cpusize: size_t, buf: *mut c_uchar) -> Result<isize> { fn do_sched_getaffinity(pid: pid_t, cpusize: size_t, buf: *mut c_uchar) -> Result<isize> {
// Construct safe Rust types // Construct safe Rust types
let mut buf_slice = { let mut buf_slice = {

@ -5,6 +5,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <libgen.h> #include <libgen.h>
#include <pwd.h> #include <pwd.h>
#include <sched.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -286,6 +287,11 @@ int ocall_sched_setaffinity(int* error, int pid, size_t cpusize, const unsigned
return ret; return ret;
} }
/* In the Linux implementation, sched_yield() always succeeds */
void ocall_sched_yield(void) {
sched_yield();
}
void ocall_sync(void) { void ocall_sync(void) {
sync(); sync();
} }

@ -154,6 +154,18 @@ static int test_sched_setaffinity_with_null_buffer() {
return 0; 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 // 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_setaffinity_with_zero_cpusetsize),
TEST_CASE(test_sched_getaffinity_with_null_buffer), TEST_CASE(test_sched_getaffinity_with_null_buffer),
TEST_CASE(test_sched_setaffinity_with_null_buffer), TEST_CASE(test_sched_setaffinity_with_null_buffer),
TEST_CASE(test_sched_yield),
}; };
int main() { int main() {