merge conflict

master
lcy1996 6 years ago
commit eb00b2bfd3

@ -0,0 +1,29 @@
#[inline(always)]
#[cfg(target_arch = "x86_64")]
pub unsafe fn disable_and_store() -> usize {
let rflags: usize;
asm!("pushfq; popq $0; cli" : "=r"(rflags));
rflags & (1 << 9)
}
#[inline(always)]
#[cfg(target_arch = "riscv32")]
pub unsafe fn disable_and_store() -> usize {
let sstatus: usize;
asm!("csrrci $0, 0x100, 1" : "=r"(sstatus));
sstatus & 1
}
#[inline(always)]
#[cfg(target_arch = "x86_64")]
pub unsafe fn restore(flags: usize) {
if flags != 0 {
asm!("sti");
}
}
#[inline(always)]
#[cfg(target_arch = "riscv32")]
pub unsafe fn restore(flags: usize) {
asm!("csrs 0x100, $0" :: "r"(flags));
}

@ -4,6 +4,7 @@
#![feature(linkage)] #![feature(linkage)]
#![feature(nll)] #![feature(nll)]
#![feature(vec_resize_default)] #![feature(vec_resize_default)]
#![feature(asm)]
#![feature(exact_size_is_empty)] #![feature(exact_size_is_empty)]
extern crate alloc; extern crate alloc;
@ -16,11 +17,12 @@ extern crate spin;
#[macro_use] #[macro_use]
extern crate std; extern crate std;
mod process_manager; pub mod process_manager;
mod processor; mod processor;
pub mod scheduler; pub mod scheduler;
pub mod thread; pub mod thread;
mod event_hub; mod event_hub;
mod interrupt;
pub use process_manager::*; pub use process_manager::*;
pub use processor::Processor; pub use processor::Processor;

@ -39,6 +39,7 @@ pub struct ProcessManager {
procs: Vec<Mutex<Option<Process>>>, procs: Vec<Mutex<Option<Process>>>,
scheduler: Mutex<Box<Scheduler>>, scheduler: Mutex<Box<Scheduler>>,
wait_queue: Vec<Mutex<Vec<Pid>>>, wait_queue: Vec<Mutex<Vec<Pid>>>,
children: Vec<Mutex<Vec<Pid>>>,
event_hub: Mutex<EventHub<Event>>, event_hub: Mutex<EventHub<Event>>,
exit_handler: fn(Pid), exit_handler: fn(Pid),
} }
@ -49,6 +50,7 @@ impl ProcessManager {
procs: new_vec_default(max_proc_num), procs: new_vec_default(max_proc_num),
scheduler: Mutex::new(scheduler), scheduler: Mutex::new(scheduler),
wait_queue: new_vec_default(max_proc_num), wait_queue: new_vec_default(max_proc_num),
children: new_vec_default(max_proc_num),
event_hub: Mutex::new(EventHub::new()), event_hub: Mutex::new(EventHub::new()),
exit_handler, exit_handler,
} }
@ -183,7 +185,7 @@ impl ProcessManager {
let mut proc_lock = self.procs[target].lock(); let mut proc_lock = self.procs[target].lock();
let proc = proc_lock.as_ref().expect("process not exist"); let proc = proc_lock.as_ref().expect("process not exist");
match proc.status { match proc.status {
Status::Exited(_) => self.wait_queue[target].lock().retain(|&i| i != pid), Status::Exited(_) => self.del_child(pid, target),
_ => panic!("can not remove non-exited process"), _ => panic!("can not remove non-exited process"),
} }
} }
@ -210,13 +212,20 @@ impl ProcessManager {
pub fn set_parent(&self, pid: Pid, target: Pid) { pub fn set_parent(&self, pid: Pid, target: Pid) {
self.wait_queue[target].lock().push(pid); self.wait_queue[target].lock().push(pid);
self.children[pid].lock().push(target);
} }
pub fn del_parent(&self, pid: Pid, target: Pid) { pub fn del_child(&self, pid: Pid, target: Pid) {
self.wait_queue[target].lock().retain(|&i| i != pid); self.wait_queue[target].lock().retain(|&i| i != pid);
self.children[pid].lock().retain(|&i| i != target);
}
pub fn get_children(&self, pid: Pid) -> Vec<Pid>{
self.children[pid].lock().clone()
} }
pub fn exit(&self, pid: Pid, code: ExitCode) { pub fn exit(&self, pid: Pid, code: ExitCode) {
(self.exit_handler)(pid); for child in self.children[pid].lock().drain(..) {
self.wait_queue[child].lock().retain(|&i| i != pid);
}
self.set_status(pid, Status::Exited(code)); self.set_status(pid, Status::Exited(code));
} }
/// Called when a process exit /// Called when a process exit
@ -226,6 +235,7 @@ impl ProcessManager {
} }
proc.context = None; proc.context = None;
(self.exit_handler)(pid);
} }
} }
fn new_vec_default<T: Default>(size: usize) -> Vec<T> { fn new_vec_default<T: Default>(size: usize) -> Vec<T> {

@ -3,6 +3,7 @@ use alloc::sync::Arc;
use spin::Mutex; use spin::Mutex;
use core::cell::UnsafeCell; use core::cell::UnsafeCell;
use process_manager::*; use process_manager::*;
use interrupt;
/// Process executor /// Process executor
/// ///
@ -52,14 +53,15 @@ impl Processor {
/// via switch back to the scheduler. /// via switch back to the scheduler.
pub fn run(&self) -> ! { pub fn run(&self) -> ! {
let inner = self.inner(); let inner = self.inner();
unsafe { interrupt::disable_and_store(); }
loop { loop {
let proc = inner.manager.run(inner.id); let proc = inner.manager.run(inner.id);
trace!("CPU{} begin running process {}", inner.id, proc.0); trace!("CPU{} begin running process {}", inner.id, proc.0);
inner.proc = Some(proc); inner.proc = Some(proc);
unsafe { unsafe {
inner.loop_context.switch_to(&mut *inner.proc.as_mut().unwrap().1); inner.loop_context.switch_to(&mut *inner.proc.as_mut().expect("context should not be None").1);
} }
let (pid, context) = inner.proc.take().unwrap(); let (pid, context) = inner.proc.take().expect("proc should not be None");
trace!("CPU{} stop running process {}", inner.id, pid); trace!("CPU{} stop running process {}", inner.id, pid);
inner.manager.stop(pid, context); inner.manager.stop(pid, context);
} }
@ -71,12 +73,17 @@ impl Processor {
trace!("yield start"); trace!("yield start");
let inner = self.inner(); let inner = self.inner();
unsafe { unsafe {
let flags = interrupt::disable_and_store();
inner.proc.as_mut().unwrap().1.switch_to(&mut *inner.loop_context); inner.proc.as_mut().unwrap().1.switch_to(&mut *inner.loop_context);
interrupt::restore(flags);
} }
} }
pub fn pid(&self) -> Pid { pub fn pid(&self) -> Pid {
self.inner().proc.as_ref().expect("pid should not be none").0 if self.inner().proc.is_none() {
return 0;
}
self.inner().proc.as_ref().expect("pid should not be None").0
} }
pub fn context(&self) -> &Context { pub fn context(&self) -> &Context {
@ -94,3 +101,4 @@ impl Processor {
} }
} }
} }

@ -97,6 +97,7 @@ pub fn spawn<F, T>(f: F) -> JoinHandle<T>
// 在Processor中创建新的线程 // 在Processor中创建新的线程
let context = new_kernel_context(kernel_thread_entry::<F, T>, f as usize); let context = new_kernel_context(kernel_thread_entry::<F, T>, f as usize);
let pid = processor().manager().add(context); let pid = processor().manager().add(context);
processor().manager().set_parent(current().id(), pid);
// 接下来看看`JoinHandle::join()`的实现 // 接下来看看`JoinHandle::join()`的实现
// 了解是如何获取f返回值的 // 了解是如何获取f返回值的

@ -20,6 +20,12 @@ _binary_user_riscv_img_end:
pub fn shell() { pub fn shell() {
// load riscv32/x86_64 user program // load riscv32/x86_64 user program
use sync;
/// below are test for sync, uncomment them if need
//sync::test::philosopher_using_mutex();
//sync::test::philosopher_using_monitor();
info!("come into shell!"); info!("come into shell!");
#[cfg(target_arch = "riscv32")] #[cfg(target_arch = "riscv32")]
let device = { let device = {
@ -43,9 +49,6 @@ pub fn shell() {
let layout = Layout::from_size_align(BUF_SIZE, 0x1000).unwrap(); let layout = Layout::from_size_align(BUF_SIZE, 0x1000).unwrap();
let buf = unsafe{ slice::from_raw_parts_mut(alloc(layout), BUF_SIZE) }; let buf = unsafe{ slice::from_raw_parts_mut(alloc(layout), BUF_SIZE) };
// start interaction // start interaction
use sync;
//sync::test::philosopher_using_mutex();
//sync::test::philosopher_using_monitor();
loop { loop {
print!(">> "); print!(">> ");

@ -31,7 +31,6 @@ pub fn init() {
static PROCESSORS: [Processor; MAX_CPU_NUM] = [Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new()]; static PROCESSORS: [Processor; MAX_CPU_NUM] = [Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new()];
/// Ugly solution for sys_wait(0) (wait for any child)
#[derive(Default)] #[derive(Default)]
pub struct Process { pub struct Process {
parent: AtomicUsize, parent: AtomicUsize,
@ -39,34 +38,9 @@ pub struct Process {
} }
impl Process { impl Process {
pub fn new_fork(pid: usize, parent: usize) {
PROCESS[pid].parent.store(parent, Ordering::Relaxed);
PROCESS[parent].children.lock().push(pid);
}
pub fn proc_exit(pid: usize) { pub fn proc_exit(pid: usize) {
info!("proc_exit"); info!("proc_exit");
for child in PROCESS[pid].children.lock().clone() {
info!("del child {}", child);
processor().manager().del_parent(pid, child);
}
}
pub fn get_children() -> Vec<usize> {
Self::current().children.lock().clone()
}
pub fn do_wait(pid: usize) {
Self::current().children.lock().retain(|&p| p != pid);
} }
fn current() -> &'static Self {
&PROCESS[thread::current().id()]
}
}
lazy_static! {
pub static ref PROCESS: Vec<Process> = {
let mut vec = Vec::new();
vec.resize_default(MAX_PROCESS_NUM);
vec
};
} }
/// Get current thread struct /// Get current thread struct

@ -105,7 +105,7 @@ fn philosopher(table: Arc<Table>) {
trace!("philosopher starting finish"); trace!("philosopher starting finish");
for h in handles { for h in handles {
h.join().expect("join expects some value"); h.join().expect("handle should not be none");
} }
println!("philosophers dining end"); println!("philosophers dining end");
} }

@ -66,7 +66,6 @@ fn sys_fork(tf: &TrapFrame) -> i32 {
//memory_set_map_swappable(context.get_memory_set_mut()); //memory_set_map_swappable(context.get_memory_set_mut());
let pid = processor().manager().add(context); let pid = processor().manager().add(context);
processor().manager().set_parent(thread::current().id(), pid); processor().manager().set_parent(thread::current().id(), pid);
Process::new_fork(pid, thread::current().id());
//memory_set_map_swappable(processor.get_context_mut(pid).get_memory_set_mut()); //memory_set_map_swappable(processor.get_context_mut(pid).get_memory_set_mut());
info!("fork: {} -> {}", thread::current().id(), pid); info!("fork: {} -> {}", thread::current().id(), pid);
pid as i32 pid as i32
@ -77,7 +76,7 @@ fn sys_fork(tf: &TrapFrame) -> i32 {
fn sys_wait(pid: usize, code: *mut i32) -> i32 { fn sys_wait(pid: usize, code: *mut i32) -> i32 {
loop { loop {
let wait_procs = match pid { let wait_procs = match pid {
0 => Process::get_children(), 0 => processor().manager().get_children(thread::current().id()),
_ => vec![pid], _ => vec![pid],
}; };
if wait_procs.is_empty() { if wait_procs.is_empty() {
@ -90,7 +89,6 @@ fn sys_wait(pid: usize, code: *mut i32) -> i32 {
unsafe { code.write(exit_code as i32); } unsafe { code.write(exit_code as i32); }
} }
processor().manager().wait_done(thread::current().id(), pid); processor().manager().wait_done(thread::current().id(), pid);
Process::do_wait(pid);
info!("wait: {} -> {}", thread::current().id(), pid); info!("wait: {} -> {}", thread::current().id(), pid);
return 0; return 0;
} }

Loading…
Cancel
Save