Refactor syscall mod and add some docs

master
WangRunji 7 years ago
parent 6c135bca24
commit a7f6ba2556

@ -50,36 +50,6 @@ pub fn print(args: fmt::Arguments) {
COM1.lock().write_fmt(args).unwrap(); COM1.lock().write_fmt(args).unwrap();
} }
pub fn 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
}
pub fn open(path: *const u8, flags: usize) -> i32 {
let path = unsafe { from_cstr(path) };
info!("open: path: {:?}, flags: {:?}", path, flags);
match path {
"stdin:" => 0,
"stdout:" => 1,
_ => -1,
}
}
pub fn close(fd: usize) -> i32 {
info!("close: fd: {:?}", fd);
0
}
pub unsafe fn from_cstr(s: *const u8) -> &'static str {
use core::{str, slice};
let len = (0usize..).find(|&i| *s.offset(i as isize) == 0).unwrap();
str::from_utf8(slice::from_raw_parts(s, len)).unwrap()
}
use log; use log;
use log::{Record, Level, Metadata, Log, SetLoggerError, LevelFilter}; use log::{Record, Level, Metadata, Log, SetLoggerError, LevelFilter};

@ -2,19 +2,14 @@ use memory::MemoryController;
use spin::{Once, Mutex}; use spin::{Once, Mutex};
use core::slice; use core::slice;
use alloc::String; use alloc::String;
use arch::interrupt::TrapFrame;
use self::process::*; use self::process::*;
use self::processor::*; pub use self::processor::*;
mod process; mod process;
mod processor; mod processor;
/// 平台相关依赖struct TrapFrame
///
/// ## 必须实现的特性
///
/// * Debug: 用于Debug输出
use arch::interrupt::TrapFrame;
pub fn init(mut mc: MemoryController) { pub fn init(mut mc: MemoryController) {
PROCESSOR.call_once(|| {Mutex::new({ PROCESSOR.call_once(|| {Mutex::new({
@ -28,8 +23,8 @@ pub fn init(mut mc: MemoryController) {
MC.call_once(|| Mutex::new(mc)); MC.call_once(|| Mutex::new(mc));
} }
static PROCESSOR: Once<Mutex<Processor>> = Once::new(); pub static PROCESSOR: Once<Mutex<Processor>> = Once::new();
static MC: Once<Mutex<MemoryController>> = Once::new(); pub static MC: Once<Mutex<MemoryController>> = Once::new();
extern fn idle_thread() { extern fn idle_thread() {
loop { loop {
@ -41,80 +36,6 @@ extern fn idle_thread() {
} }
} }
/// Fork the current process. Return the child's PID.
pub fn sys_fork(tf: &TrapFrame) -> i32 {
let mut processor = PROCESSOR.try().unwrap().lock();
let mut mc = MC.try().unwrap().lock();
let new = processor.current().fork(tf, &mut mc);
let pid = processor.add(new);
info!("fork: {} -> {}", processor.current().pid, pid);
pid as i32
}
/// Wait the process exit.
/// Return the PID. Store exit code to `code` if it's not null.
pub fn sys_wait(rsp: &mut usize, pid: usize, code: *mut i32) -> i32 {
let mut processor = PROCESSOR.try().unwrap().lock();
let target = match pid {
0 => WaitTarget::AnyChild,
_ => WaitTarget::Proc(pid),
};
match processor.current_wait_for(target) {
WaitResult::Ok(pid, error_code) => {
if !code.is_null() {
unsafe { *code = error_code as i32 };
}
0 // pid as i32
},
WaitResult::Blocked => {
processor.schedule(rsp);
0 /* unused */
},
WaitResult::NotExist => -1,
}
}
pub fn sys_yield(rsp: &mut usize) -> i32 {
info!("yield:");
let mut processor = PROCESSOR.try().unwrap().lock();
processor.schedule(rsp);
0
}
/// Kill the process
pub fn sys_kill(pid: usize) -> i32 {
PROCESSOR.try().unwrap().lock().kill(pid);
0
}
/// Get the current process id
pub fn sys_getpid() -> i32 {
PROCESSOR.try().unwrap().lock().current().pid as i32
}
/// Exit the current process
pub fn sys_exit(rsp: &mut usize, error_code: ErrorCode) -> i32 {
let mut processor = PROCESSOR.try().unwrap().lock();
let pid = processor.current().pid;
processor.schedule(rsp);
processor.exit(pid, error_code);
0
}
pub fn sys_sleep(rsp: &mut usize, time: usize) -> i32 {
info!("sleep: {} ticks", time);
let mut processor = PROCESSOR.try().unwrap().lock();
let pid = processor.current().pid;
processor.schedule(rsp);
processor.sleep(pid, time);
0
}
pub fn sys_get_time() -> i32 {
let processor = PROCESSOR.try().unwrap().lock();
processor.get_time() as i32
}
pub fn timer_handler(tf: &TrapFrame, rsp: &mut usize) { pub fn timer_handler(tf: &TrapFrame, rsp: &mut usize) {
let mut processor = PROCESSOR.try().unwrap().lock(); let mut processor = PROCESSOR.try().unwrap().lock();
processor.tick(rsp); processor.tick(rsp);

@ -1,6 +1,6 @@
use alloc::BTreeMap; use alloc::BTreeMap;
use memory::{ActivePageTable, InactivePageTable}; use memory::{ActivePageTable, InactivePageTable};
use super::*; use super::process::*;
use core::cell::RefCell; use core::cell::RefCell;
use core::fmt::{Debug, Formatter, Error}; use core::fmt::{Debug, Formatter, Error};
use util::{EventHub, GetMut2}; use util::{EventHub, GetMut2};
@ -135,6 +135,9 @@ impl Processor {
pub fn current(&self) -> &Process { pub fn current(&self) -> &Process {
self.get(self.current_pid) self.get(self.current_pid)
} }
pub fn current_pid(&self) -> Pid {
self.current_pid
}
pub fn kill(&mut self, pid: Pid) { pub fn kill(&mut self, pid: Pid) {
self.exit(pid, 0x1000); // TODO: error code for killed self.exit(pid, 0x1000); // TODO: error code for killed

@ -1,7 +1,14 @@
use super::*; //! 系统调用解析执行模块
use process;
use arch::interrupt::TrapFrame; use arch::interrupt::TrapFrame;
use process::*;
use util;
/// 系统调用入口点
///
/// 当发生系统调用中断时,中断服务例程将控制权转移到这里。
/// 它从中断帧中提取参数,根据系统调用号分发执行具体操作。
/// 它同时支持 xv6的64位程序 和 uCore的32位程序。
pub fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 { pub fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 {
let id = match is32 { let id = match is32 {
false => Syscall::Xv6(tf.rax), false => Syscall::Xv6(tf.rax),
@ -16,27 +23,27 @@ pub fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 {
match id { match id {
Syscall::Xv6(SYS_WRITE) | Syscall::Ucore(UCORE_SYS_WRITE) => Syscall::Xv6(SYS_WRITE) | Syscall::Ucore(UCORE_SYS_WRITE) =>
io::write(args[0], args[1] as *const u8, args[2]), sys_write(args[0], args[1] as *const u8, args[2]),
Syscall::Xv6(SYS_OPEN) | Syscall::Ucore(UCORE_SYS_OPEN) => Syscall::Xv6(SYS_OPEN) | Syscall::Ucore(UCORE_SYS_OPEN) =>
io::open(args[0] as *const u8, args[1]), sys_open(args[0] as *const u8, args[1]),
Syscall::Xv6(SYS_CLOSE) | Syscall::Ucore(UCORE_SYS_CLOSE) => Syscall::Xv6(SYS_CLOSE) | Syscall::Ucore(UCORE_SYS_CLOSE) =>
io::close(args[0]), sys_close(args[0]),
Syscall::Xv6(SYS_WAIT) | Syscall::Ucore(UCORE_SYS_WAIT) => Syscall::Xv6(SYS_WAIT) | Syscall::Ucore(UCORE_SYS_WAIT) =>
process::sys_wait(rsp, args[0], args[1] as *mut i32), sys_wait(rsp, args[0], args[1] as *mut i32),
Syscall::Xv6(SYS_FORK) | Syscall::Ucore(UCORE_SYS_FORK) => Syscall::Xv6(SYS_FORK) | Syscall::Ucore(UCORE_SYS_FORK) =>
process::sys_fork(tf), sys_fork(tf),
Syscall::Xv6(SYS_KILL) | Syscall::Ucore(UCORE_SYS_KILL) => Syscall::Xv6(SYS_KILL) | Syscall::Ucore(UCORE_SYS_KILL) =>
process::sys_kill(args[0]), sys_kill(args[0]),
Syscall::Xv6(SYS_EXIT) | Syscall::Ucore(UCORE_SYS_EXIT) => Syscall::Xv6(SYS_EXIT) | Syscall::Ucore(UCORE_SYS_EXIT) =>
process::sys_exit(rsp, args[0]), sys_exit(rsp, args[0]),
Syscall::Ucore(UCORE_SYS_YIELD) => Syscall::Ucore(UCORE_SYS_YIELD) =>
process::sys_yield(rsp), sys_yield(rsp),
Syscall::Ucore(UCORE_SYS_GETPID) => Syscall::Ucore(UCORE_SYS_GETPID) =>
process::sys_getpid(), sys_getpid(),
Syscall::Ucore(UCORE_SYS_SLEEP) => Syscall::Ucore(UCORE_SYS_SLEEP) =>
process::sys_sleep(rsp, args[0]), sys_sleep(rsp, args[0]),
Syscall::Ucore(UCORE_SYS_GETTIME) => Syscall::Ucore(UCORE_SYS_GETTIME) =>
process::sys_get_time(), sys_get_time(),
Syscall::Ucore(UCORE_SYS_PUTC) => Syscall::Ucore(UCORE_SYS_PUTC) =>
{ {
print!("{}", args[0] as u8 as char); print!("{}", args[0] as u8 as char);
@ -49,6 +56,105 @@ pub fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 {
} }
} }
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 {
let mut processor = PROCESSOR.try().unwrap().lock();
let mut mc = MC.try().unwrap().lock();
let new = processor.current().fork(tf, &mut mc);
let pid = processor.add(new);
info!("fork: {} -> {}", processor.current_pid(), pid);
pid as i32
}
/// Wait the process exit.
/// Return the PID. Store exit code to `code` if it's not null.
fn sys_wait(rsp: &mut usize, pid: usize, code: *mut i32) -> i32 {
let mut processor = PROCESSOR.try().unwrap().lock();
let target = match pid {
0 => WaitTarget::AnyChild,
_ => WaitTarget::Proc(pid),
};
match processor.current_wait_for(target) {
WaitResult::Ok(pid, error_code) => {
if !code.is_null() {
unsafe { *code = error_code as i32 };
}
0 // pid as i32
},
WaitResult::Blocked => {
processor.schedule(rsp);
0 /* unused */
},
WaitResult::NotExist => -1,
}
}
fn sys_yield(rsp: &mut usize) -> i32 {
info!("yield:");
let mut processor = PROCESSOR.try().unwrap().lock();
processor.schedule(rsp);
0
}
/// Kill the process
fn sys_kill(pid: usize) -> i32 {
PROCESSOR.try().unwrap().lock().kill(pid);
0
}
/// Get the current process id
fn sys_getpid() -> i32 {
PROCESSOR.try().unwrap().lock().current_pid() as i32
}
/// Exit the current process
fn sys_exit(rsp: &mut usize, error_code: usize) -> i32 {
let mut processor = PROCESSOR.try().unwrap().lock();
let pid = processor.current_pid();
processor.schedule(rsp);
processor.exit(pid, error_code);
0
}
fn sys_sleep(rsp: &mut usize, time: usize) -> i32 {
info!("sleep: {} ticks", time);
let mut processor = PROCESSOR.try().unwrap().lock();
let pid = processor.current_pid();
processor.schedule(rsp);
processor.sleep(pid, time);
0
}
fn sys_get_time() -> i32 {
let processor = PROCESSOR.try().unwrap().lock();
processor.get_time() as i32
}
#[derive(Debug)] #[derive(Debug)]
enum Syscall { enum Syscall {
Xv6(usize), Xv6(usize),

@ -19,6 +19,13 @@ pub unsafe fn find_in_memory<T: Checkable>
.find(|&addr| { (&*(addr as *const T)).check() }) .find(|&addr| { (&*(addr as *const T)).check() })
} }
/// Convert C string to Rust string
pub unsafe fn from_cstr(s: *const u8) -> &'static str {
use core::{str, slice};
let len = (0usize..).find(|&i| *s.offset(i as isize) == 0).unwrap();
str::from_utf8(slice::from_raw_parts(s, len)).unwrap()
}
use core::ops::IndexMut; use core::ops::IndexMut;
use core::fmt::Debug; use core::fmt::Debug;

Loading…
Cancel
Save