2018-04-27 19:10:39 +04:00
|
|
|
|
use memory::MemoryController;
|
|
|
|
|
use spin::{Once, Mutex};
|
2018-05-13 11:06:44 +04:00
|
|
|
|
use core::slice;
|
2018-05-18 07:49:27 +04:00
|
|
|
|
use alloc::String;
|
2018-04-27 19:10:39 +04:00
|
|
|
|
|
|
|
|
|
use self::process::*;
|
|
|
|
|
use self::processor::*;
|
|
|
|
|
|
|
|
|
|
mod process;
|
|
|
|
|
mod processor;
|
|
|
|
|
|
|
|
|
|
/// 平台相关依赖:struct TrapFrame
|
|
|
|
|
///
|
|
|
|
|
/// ## 必须实现的特性
|
|
|
|
|
///
|
|
|
|
|
/// * Debug: 用于Debug输出
|
|
|
|
|
use arch::interrupt::TrapFrame;
|
|
|
|
|
|
2018-05-13 17:13:57 +04:00
|
|
|
|
pub fn init(mut mc: MemoryController) {
|
2018-04-27 19:10:39 +04:00
|
|
|
|
PROCESSOR.call_once(|| {Mutex::new({
|
2018-05-13 17:13:57 +04:00
|
|
|
|
let initproc = Process::new_init(&mut mc);
|
|
|
|
|
let idleproc = Process::new("idle", idle_thread, &mut mc);
|
2018-05-18 07:49:27 +04:00
|
|
|
|
let mut processor = Processor::new();
|
2018-04-27 19:10:39 +04:00
|
|
|
|
processor.add(initproc);
|
|
|
|
|
processor.add(idleproc);
|
|
|
|
|
processor
|
|
|
|
|
})});
|
2018-05-18 07:49:27 +04:00
|
|
|
|
MC.call_once(|| Mutex::new(mc));
|
2018-04-27 19:10:39 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PROCESSOR: Once<Mutex<Processor>> = Once::new();
|
2018-05-18 07:49:27 +04:00
|
|
|
|
static MC: Once<Mutex<MemoryController>> = Once::new();
|
2018-04-27 19:10:39 +04:00
|
|
|
|
|
|
|
|
|
/// Called by timer handler in arch
|
|
|
|
|
/// 设置rsp,指向接下来要执行线程的 内核栈顶
|
|
|
|
|
/// 之后中断处理例程会重置rsp,恢复对应线程的上下文
|
|
|
|
|
pub fn schedule(rsp: &mut usize) {
|
|
|
|
|
PROCESSOR.try().unwrap().lock().schedule(rsp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern fn idle_thread() {
|
|
|
|
|
loop {
|
|
|
|
|
println!("idle ...");
|
|
|
|
|
let mut i = 0;
|
|
|
|
|
while i < 1 << 22 {
|
|
|
|
|
i += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-12 23:41:41 +04:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-19 12:32:18 +04:00
|
|
|
|
/// Fork the current process. Return the child's PID.
|
2018-05-17 18:15:26 +04:00
|
|
|
|
pub fn sys_fork(tf: &TrapFrame) -> i32 {
|
2018-05-18 07:49:27 +04:00
|
|
|
|
let mut processor = PROCESSOR.try().unwrap().lock();
|
|
|
|
|
let mut mc = MC.try().unwrap().lock();
|
|
|
|
|
let new = processor.current().fork(tf, &mut mc);
|
2018-05-19 12:32:18 +04:00
|
|
|
|
let pid = processor.add(new);
|
2018-05-19 14:42:08 +04:00
|
|
|
|
info!("fork: {} -> {}", processor.current().pid, pid);
|
2018-05-19 12:32:18 +04:00
|
|
|
|
pid as i32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Wait the process exit. Return the exit code.
|
|
|
|
|
pub fn sys_wait(rsp: &mut usize, pid: usize) -> 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(error_code) => error_code as i32,
|
|
|
|
|
WaitResult::Blocked => {
|
|
|
|
|
processor.schedule(rsp);
|
|
|
|
|
0 /* unused */
|
|
|
|
|
},
|
|
|
|
|
WaitResult::NotExist => { -1 }
|
|
|
|
|
}
|
2018-05-17 18:15:26 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 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
|
2018-05-19 12:32:18 +04:00
|
|
|
|
pub fn sys_exit(rsp: &mut usize, error_code: ErrorCode) -> i32 {
|
2018-05-17 18:15:26 +04:00
|
|
|
|
let mut processor = PROCESSOR.try().unwrap().lock();
|
|
|
|
|
let pid = processor.current().pid;
|
|
|
|
|
processor.schedule(rsp);
|
|
|
|
|
processor.exit(pid, error_code);
|
|
|
|
|
0
|
2018-05-18 07:49:27 +04:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-19 20:22:52 +04:00
|
|
|
|
pub fn sys_sleep(rsp: &mut usize, time: usize) -> i32 {
|
|
|
|
|
info!("sleep: {} ticks", time);
|
|
|
|
|
unimplemented!()
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-19 12:32:18 +04:00
|
|
|
|
pub fn add_user_process(name: impl AsRef<str>, data: &[u8]) {
|
2018-05-18 07:49:27 +04:00
|
|
|
|
let mut processor = PROCESSOR.try().unwrap().lock();
|
|
|
|
|
let mut mc = MC.try().unwrap().lock();
|
|
|
|
|
let mut new = Process::new_user(data, &mut mc);
|
2018-05-19 12:32:18 +04:00
|
|
|
|
new.name = String::from(name.as_ref());
|
2018-05-18 07:49:27 +04:00
|
|
|
|
processor.add(new);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn print() {
|
|
|
|
|
debug!("{:#x?}", *PROCESSOR.try().unwrap().lock());
|
2018-04-27 19:10:39 +04:00
|
|
|
|
}
|