Add spawn and wait4 test

This commit is contained in:
Tate, Hongliang Tian 2019-01-04 21:09:28 +08:00
parent d960792ef3
commit 5b7048976e
6 changed files with 64 additions and 13 deletions

@ -40,7 +40,7 @@ impl<D, R> Waiter<D, R>
pub fn wait_on(&self) -> R { pub fn wait_on(&self) -> R {
if !self.inner.lock().unwrap().has_waken { if !self.inner.lock().unwrap().has_waken {
unsafe { unsafe {
sgx_thread_wait_untrusted_event_ocall(self.thread); wait_event(self.thread);
} }
} }
@ -93,27 +93,47 @@ impl<D, R> WaitQueue<D, R>
waiter_i.unwrap() waiter_i.unwrap()
}; };
let del_waiter = waiters.swap_remove(del_waiter_i); let del_waiter = waiters.swap_remove(del_waiter_i);
unsafe { set_event(del_waiter.thread);
sgx_thread_set_untrusted_event_ocall(del_waiter.thread);
}
1 1
} }
} }
fn wait_event(thread: *const c_void) {
let mut ret : c_int = 0;
let mut sgx_ret : c_int = 0;
unsafe {
sgx_ret = sgx_thread_wait_untrusted_event_ocall(&mut ret as *mut c_int, thread);
}
if ret != 0 || sgx_ret != 0 {
panic!("ERROR: OCall failed!");
}
}
fn set_event(thread: *const c_void) {
let mut ret : c_int = 0;
let mut sgx_ret : c_int = 0;
unsafe {
sgx_ret = sgx_thread_set_untrusted_event_ocall(&mut ret as *mut c_int, thread);
}
if ret != 0 || sgx_ret != 0 {
panic!("ERROR: OCall failed!");
}
}
extern { extern {
fn sgx_thread_get_self() -> *const c_void; fn sgx_thread_get_self() -> *const c_void;
/* Go outside and wait on my untrusted event */ /* Go outside and wait on my untrusted event */
fn sgx_thread_wait_untrusted_event_ocall(self_thread: *const c_void) -> c_int; fn sgx_thread_wait_untrusted_event_ocall(ret: *mut c_int, self_thread: *const c_void) -> c_int;
/* Wake a thread waiting on its untrusted event */ /* Wake a thread waiting on its untrusted event */
fn sgx_thread_set_untrusted_event_ocall(waiter_thread: *const c_void) -> c_int; fn sgx_thread_set_untrusted_event_ocall(ret: *mut c_int, waiter_thread: *const c_void) -> c_int;
/* Wake a thread waiting on its untrusted event, and wait on my untrusted event */ /* Wake a thread waiting on its untrusted event, and wait on my untrusted event */
fn sgx_thread_setwait_untrusted_events_ocall( fn sgx_thread_setwait_untrusted_events_ocall(ret: *mut c_int,
waiter_thread: *const c_void, self_thread: *const c_void) -> c_int; waiter_thread: *const c_void, self_thread: *const c_void) -> c_int;
/* Wake multiple threads waiting on their untrusted events */ /* Wake multiple threads waiting on their untrusted events */
fn sgx_thread_set_multiple_untrusted_events_ocall( fn sgx_thread_set_multiple_untrusted_events_ocall(ret: *mut c_int,
waiter_threads: *const *const c_void, total: size_t ) -> c_int; waiter_threads: *const *const c_void, total: size_t ) -> c_int;
} }

@ -378,7 +378,9 @@ pub extern "C" fn occlum_spawn(
} }
fn do_wait4(pid: c_int, _exit_status: *mut c_int) -> Result<pid_t, Error> { fn do_wait4(pid: c_int, _exit_status: *mut c_int) -> Result<pid_t, Error> {
if _exit_status != 0 as *mut c_int {
check_mut_ptr_from_user(_exit_status)?; check_mut_ptr_from_user(_exit_status)?;
}
let child_process_filter = match pid { let child_process_filter = match pid {
pid if pid < -1 => { pid if pid < -1 => {
@ -401,7 +403,9 @@ fn do_wait4(pid: c_int, _exit_status: *mut c_int) -> Result<pid_t, Error> {
let mut exit_status = 0; let mut exit_status = 0;
match process::do_wait4(&child_process_filter, &mut exit_status) { match process::do_wait4(&child_process_filter, &mut exit_status) {
Ok(pid) => { Ok(pid) => {
if _exit_status != 0 as *mut c_int {
unsafe { *_exit_status = exit_status; } unsafe { *_exit_status = exit_status; }
}
Ok(pid) Ok(pid)
} }
Err(e) => { Err(e) => {

@ -1,7 +1,7 @@
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PROJECT_DIR := $(realpath $(CUR_DIR)/../) PROJECT_DIR := $(realpath $(CUR_DIR)/../)
TEST_SUITES := empty hello_world malloc getpid TEST_SUITES := empty hello_world malloc getpid spawn
BUILD_TEST_SUITES := $(TEST_SUITES:%=%) BUILD_TEST_SUITES := $(TEST_SUITES:%=%)
RUN_TEST_SUITES := $(TEST_SUITES:%=run-%) RUN_TEST_SUITES := $(TEST_SUITES:%=run-%)
CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%) CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%)

@ -3,7 +3,6 @@
#include <stdio.h> #include <stdio.h>
int main(void) { int main(void) {
printf("pid = %d\n", getpid()); printf("Run a new process with pid = %d and ppid = %d\n", getpid(), getppid());
printf("ppid = %d\n", getppid());
return 0; return 0;
} }

4
test/spawn/Makefile Normal file

@ -0,0 +1,4 @@
include ../test_common.mk
EXTRA_C_FLAGS :=
EXTRA_LINK_FLAGS :=

24
test/spawn/main.c Normal file

@ -0,0 +1,24 @@
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
int ret, child_pid, status;
printf("Run a parent process has pid = %d and ppid = %d\n", getpid(), getppid());
ret = syscall(__NR_spawn, &child_pid, "getpid/bin.encrypted", NULL, NULL);
if (ret < 0) {
printf("ERROR: failed to spawn a child process\n");
return -1;
}
printf("Spawn a new proces successfully (pid = %d)\n", child_pid);
ret = syscall(__NR_wait4, -1, &status, 0);
if (ret < 0) {
printf("ERROR: failed to wait4 the child process\n");
return -1;
}
printf("Child process exited with status = %d\n", status);
return 0;
}