2018-05-21 12:30:30 +04:00
|
|
|
//! 系统调用解析执行模块
|
|
|
|
|
2018-06-03 19:05:43 +04:00
|
|
|
#![allow(unused)]
|
|
|
|
|
2018-05-12 23:41:41 +04:00
|
|
|
use arch::interrupt::TrapFrame;
|
2018-05-21 12:30:30 +04:00
|
|
|
use process::*;
|
2018-05-31 16:26:25 +04:00
|
|
|
use thread;
|
2018-05-21 12:30:30 +04:00
|
|
|
use util;
|
2018-05-12 23:41:41 +04:00
|
|
|
|
2018-11-05 16:37:05 +04:00
|
|
|
use process::context::memory_set_map_swappable;
|
2018-11-05 18:16:45 +04:00
|
|
|
use alloc::boxed::Box;
|
|
|
|
use process::context::*;
|
2018-11-05 16:37:05 +04:00
|
|
|
|
2018-05-21 12:30:30 +04:00
|
|
|
/// 系统调用入口点
|
|
|
|
///
|
|
|
|
/// 当发生系统调用中断时,中断服务例程将控制权转移到这里。
|
2018-07-14 08:28:55 +04:00
|
|
|
pub fn syscall(id: usize, args: [usize; 6], tf: &TrapFrame) -> i32 {
|
2018-05-12 23:41:41 +04:00
|
|
|
match id {
|
2018-07-14 08:28:55 +04:00
|
|
|
SYS_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
|
|
|
|
SYS_OPEN => sys_open(args[0] as *const u8, args[1]),
|
|
|
|
SYS_CLOSE => sys_close(args[0]),
|
|
|
|
SYS_WAIT => sys_wait(args[0], args[1] as *mut i32),
|
|
|
|
SYS_FORK => sys_fork(tf),
|
|
|
|
SYS_KILL => sys_kill(args[0]),
|
|
|
|
SYS_EXIT => sys_exit(args[0]),
|
|
|
|
SYS_YIELD => sys_yield(),
|
|
|
|
SYS_GETPID => sys_getpid(),
|
|
|
|
SYS_SLEEP => sys_sleep(args[0]),
|
|
|
|
SYS_GETTIME => sys_get_time(),
|
|
|
|
SYS_LAB6_SET_PRIORITY => sys_lab6_set_priority(args[0]),
|
|
|
|
SYS_PUTC => sys_putc(args[0] as u8 as char),
|
2018-05-12 23:41:41 +04:00
|
|
|
_ => {
|
2018-07-14 14:42:58 +04:00
|
|
|
error!("unknown syscall id: {:#x?}, args: {:x?}", id, args);
|
2018-07-17 08:07:21 +04:00
|
|
|
::trap::error(tf);
|
2018-05-19 20:22:52 +04:00
|
|
|
}
|
2018-05-12 23:41:41 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-21 12:30:30 +04:00
|
|
|
fn sys_write(fd: usize, base: *const u8, len: usize) -> i32 {
|
|
|
|
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
|
|
|
|
use core::slice;
|
|
|
|
use core::str;
|
|
|
|
let slice = unsafe { slice::from_raw_parts(base, len) };
|
|
|
|
print!("{}", str::from_utf8(slice).unwrap());
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sys_open(path: *const u8, flags: usize) -> i32 {
|
|
|
|
let path = unsafe { util::from_cstr(path) };
|
|
|
|
info!("open: path: {:?}, flags: {:?}", path, flags);
|
|
|
|
match path {
|
|
|
|
"stdin:" => 0,
|
|
|
|
"stdout:" => 1,
|
|
|
|
_ => -1,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sys_close(fd: usize) -> i32 {
|
|
|
|
info!("close: fd: {:?}", fd);
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Fork the current process. Return the child's PID.
|
|
|
|
fn sys_fork(tf: &TrapFrame) -> i32 {
|
2018-11-03 17:45:03 +04:00
|
|
|
let mut context = process().fork(tf);
|
2018-11-05 18:16:45 +04:00
|
|
|
//memory_set_map_swappable(context.get_memory_set_mut());
|
2018-11-03 17:45:03 +04:00
|
|
|
let pid = processor().manager().add(context);
|
|
|
|
Process::new_fork(pid, thread::current().id());
|
2018-11-05 17:31:04 +04:00
|
|
|
//memory_set_map_swappable(processor.get_context_mut(pid).get_memory_set_mut());
|
2018-11-03 17:45:03 +04:00
|
|
|
info!("fork: {} -> {}", thread::current().id(), pid);
|
2018-05-21 12:30:30 +04:00
|
|
|
pid as i32
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Wait the process exit.
|
|
|
|
/// Return the PID. Store exit code to `code` if it's not null.
|
2018-05-21 16:07:20 +04:00
|
|
|
fn sys_wait(pid: usize, code: *mut i32) -> i32 {
|
2018-11-03 17:45:03 +04:00
|
|
|
loop {
|
|
|
|
let wait_procs = match pid {
|
|
|
|
0 => Process::get_children(),
|
|
|
|
_ => vec![pid],
|
|
|
|
};
|
|
|
|
if wait_procs.is_empty() {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
for pid in wait_procs {
|
|
|
|
match processor().manager().get_status(pid) {
|
|
|
|
Some(Status::Exited(exit_code)) => {
|
|
|
|
if !code.is_null() {
|
|
|
|
unsafe { code.write(exit_code as i32); }
|
|
|
|
}
|
|
|
|
processor().manager().remove(pid);
|
|
|
|
Process::do_wait(pid);
|
|
|
|
info!("wait: {} -> {}", thread::current().id(), pid);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
None => return -1,
|
|
|
|
_ => {}
|
2018-05-22 21:35:46 +04:00
|
|
|
}
|
2018-07-14 08:28:55 +04:00
|
|
|
}
|
2018-11-03 17:45:03 +04:00
|
|
|
if pid == 0 {
|
|
|
|
Process::wait_child();
|
|
|
|
} else {
|
|
|
|
processor().manager().wait(thread::current().id(), pid);
|
|
|
|
processor().yield_now();
|
|
|
|
}
|
2018-05-21 12:30:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-21 16:07:20 +04:00
|
|
|
fn sys_yield() -> i32 {
|
2018-05-31 16:26:25 +04:00
|
|
|
thread::yield_now();
|
2018-05-21 12:30:30 +04:00
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Kill the process
|
|
|
|
fn sys_kill(pid: usize) -> i32 {
|
2018-11-03 17:45:03 +04:00
|
|
|
processor().manager().exit(pid, 0x100);
|
|
|
|
Process::proc_exit(pid);
|
|
|
|
if pid == thread::current().id() {
|
|
|
|
processor().yield_now();
|
|
|
|
}
|
2018-05-21 12:30:30 +04:00
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the current process id
|
|
|
|
fn sys_getpid() -> i32 {
|
2018-05-31 16:26:25 +04:00
|
|
|
thread::current().id() as i32
|
2018-05-21 12:30:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Exit the current process
|
2018-11-03 17:45:03 +04:00
|
|
|
fn sys_exit(exit_code: usize) -> i32 {
|
|
|
|
let pid = thread::current().id();
|
|
|
|
processor().manager().exit(pid, exit_code);
|
|
|
|
Process::proc_exit(pid);
|
|
|
|
processor().yield_now();
|
|
|
|
unreachable!();
|
2018-05-21 12:30:30 +04:00
|
|
|
}
|
|
|
|
|
2018-05-21 16:07:20 +04:00
|
|
|
fn sys_sleep(time: usize) -> i32 {
|
2018-06-01 07:47:58 +04:00
|
|
|
use core::time::Duration;
|
|
|
|
thread::sleep(Duration::from_millis(time as u64 * 10));
|
2018-05-21 12:30:30 +04:00
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sys_get_time() -> i32 {
|
2018-11-03 17:45:03 +04:00
|
|
|
unsafe { ::trap::TICK as i32 }
|
2018-05-21 12:30:30 +04:00
|
|
|
}
|
|
|
|
|
2018-05-23 08:41:13 +04:00
|
|
|
fn sys_lab6_set_priority(priority: usize) -> i32 {
|
2018-11-03 17:45:03 +04:00
|
|
|
let pid = thread::current().id();
|
|
|
|
processor().manager().set_priority(pid, priority as u8);
|
2018-05-23 08:41:13 +04:00
|
|
|
0
|
|
|
|
}
|
|
|
|
|
2018-07-14 08:28:55 +04:00
|
|
|
fn sys_putc(c: char) -> i32 {
|
|
|
|
print!("{}", c);
|
|
|
|
0
|
2018-05-17 18:15:26 +04:00
|
|
|
}
|
|
|
|
|
2018-07-14 08:28:55 +04:00
|
|
|
const SYS_EXIT: usize = 1;
|
|
|
|
const SYS_FORK: usize = 2;
|
2018-05-12 23:41:41 +04:00
|
|
|
const SYS_WAIT: usize = 3;
|
2018-07-14 08:28:55 +04:00
|
|
|
const SYS_EXEC: usize = 4;
|
|
|
|
const SYS_CLONE: usize = 5;
|
|
|
|
const SYS_YIELD: usize = 10;
|
|
|
|
const SYS_SLEEP: usize = 11;
|
|
|
|
const SYS_KILL: usize = 12;
|
|
|
|
const SYS_GETTIME: usize = 17;
|
|
|
|
const SYS_GETPID: usize = 18;
|
|
|
|
const SYS_MMAP: usize = 20;
|
|
|
|
const SYS_MUNMAP: usize = 21;
|
|
|
|
const SYS_SHMEM: usize = 22;
|
|
|
|
const SYS_PUTC: usize = 30;
|
|
|
|
const SYS_PGDIR: usize = 31;
|
|
|
|
const SYS_OPEN: usize = 100;
|
|
|
|
const SYS_CLOSE: usize = 101;
|
|
|
|
const SYS_READ: usize = 102;
|
|
|
|
const SYS_WRITE: usize = 103;
|
|
|
|
const SYS_SEEK: usize = 104;
|
|
|
|
const SYS_FSTAT: usize = 110;
|
|
|
|
const SYS_FSYNC: usize = 111;
|
|
|
|
const SYS_GETCWD: usize = 121;
|
|
|
|
const SYS_GETDIRENTRY: usize = 128;
|
|
|
|
const SYS_DUP: usize = 130;
|
|
|
|
const SYS_LAB6_SET_PRIORITY: usize = 255;
|