Code transplanting: Fix bugs. Pass test 'spin'

master
lcy1996 6 years ago
parent 4a92a4c6a1
commit 9adcea44d5

@ -288,6 +288,7 @@ impl<T: PageTable, M: SwapManager, S: Swapper> SwapExt<T, M, S> {
//info!("got entry!"); //info!("got entry!");
!entry.present() && !entry.swapped() !entry.present() && !entry.swapped()
}; };
info!("need_alloc got");
if need_alloc { if need_alloc {
info!("need_alloc!"); info!("need_alloc!");
let frame = alloc_frame(); let frame = alloc_frame();
@ -307,6 +308,7 @@ impl<T: PageTable, M: SwapManager, S: Swapper> SwapExt<T, M, S> {
info!("allocated successfully"); info!("allocated successfully");
return true; return true;
} }
info!("not need alloc!");
} }
// now we didn't attach the cow so the present will be false when swapped(), to enable the cow some changes will be needed // now we didn't attach the cow so the present will be false when swapped(), to enable the cow some changes will be needed
if !self.page_table.get_entry(addr).swapped() { if !self.page_table.get_entry(addr).swapped() {

@ -39,23 +39,17 @@ pub struct ProcessManager {
scheduler: Mutex<Box<Scheduler>>, scheduler: Mutex<Box<Scheduler>>,
wait_queue: Vec<Mutex<Vec<Pid>>>, wait_queue: Vec<Mutex<Vec<Pid>>>,
event_hub: Mutex<EventHub<Event>>, event_hub: Mutex<EventHub<Event>>,
exit_handler: fn(Pid),
} }
impl ProcessManager { impl ProcessManager {
pub fn new(scheduler: Box<Scheduler>, max_proc_num: usize) -> Self { pub fn new(scheduler: Box<Scheduler>, max_proc_num: usize, exit_handler: fn(Pid)) -> Self {
ProcessManager { ProcessManager {
procs: { procs: new_vec_default(max_proc_num),
let mut vec = Vec::new();
vec.resize_default(max_proc_num);
vec
},
scheduler: Mutex::new(scheduler), scheduler: Mutex::new(scheduler),
wait_queue: { wait_queue: new_vec_default(max_proc_num),
let mut vec = Vec::new();
vec.resize_default(max_proc_num);
vec
},
event_hub: Mutex::new(EventHub::new()), event_hub: Mutex::new(EventHub::new()),
exit_handler,
} }
} }
@ -124,7 +118,7 @@ impl ProcessManager {
proc.context = Some(context); proc.context = Some(context);
match proc.status { match proc.status {
Status::Ready => self.scheduler.lock().insert(pid), Status::Ready => self.scheduler.lock().insert(pid),
Status::Exited(_) => proc.context = None, Status::Exited(_) => self.exit_handler(pid, proc),
_ => {} _ => {}
} }
} }
@ -152,7 +146,7 @@ impl ProcessManager {
_ => proc.status = status, _ => proc.status = status,
} }
match proc.status { match proc.status {
Status::Exited(_) => proc.context = None, Status::Exited(_) => self.exit_handler(pid, proc),
_ => {} _ => {}
} }
} }
@ -189,8 +183,18 @@ impl ProcessManager {
pub fn exit(&self, pid: Pid, code: ExitCode) { pub fn exit(&self, pid: Pid, code: ExitCode) {
self.set_status(pid, Status::Exited(code)); self.set_status(pid, Status::Exited(code));
}
/// Called when a process exit
fn exit_handler(&self, pid: Pid, proc: &mut Process) {
for waiter in self.wait_queue[pid].lock().drain(..) { for waiter in self.wait_queue[pid].lock().drain(..) {
self.wakeup(waiter); self.wakeup(waiter);
} }
proc.context = None;
(self.exit_handler)(pid);
}
} }
fn new_vec_default<T: Default>(size: usize) -> Vec<T> {
let mut vec = Vec::new();
vec.resize_default(size);
vec
} }

@ -119,22 +119,26 @@ pub fn page_fault_handler(addr: usize) -> bool {
info!("start handling swap in/out page fault"); info!("start handling swap in/out page fault");
unsafe { ACTIVE_TABLE_SWAP.force_unlock(); } unsafe { ACTIVE_TABLE_SWAP.force_unlock(); }
debug!("active page table token in pg fault is {:x?}", ActivePageTable::token()); info!("active page table token in pg fault is {:x?}", ActivePageTable::token());
let id = memory_set_record().iter() let id = memory_set_record().iter()
.position(|x| unsafe{(*(x.clone() as *mut MemorySet)).get_page_table_mut().token() == ActivePageTable::token()}); .position(|x| unsafe{(*(x.clone() as *mut MemorySet)).get_page_table_mut().token() == ActivePageTable::token()});
info!("id got");
let mut mmsets = memory_set_record(); let mut mmsets = memory_set_record();
info!("mmset got");
match id { match id {
Some(targetid) => { Some(targetid) => {
debug!("get id from memroy set recorder."); info!("get id from memroy set recorder.");
let mmset_ptr = mmsets.get(targetid); let mmset_ptr = mmsets.get(targetid);
let pt = unsafe { (*(mmset_ptr.unwrap().clone() as *mut MemorySet)).get_page_table_mut() }; let pt = unsafe { (*(mmset_ptr.unwrap().clone() as *mut MemorySet)).get_page_table_mut() };
info!("pt got!");
if active_table_swap().page_fault_handler(pt as *mut InactivePageTable0, addr, false, || alloc_frame().unwrap()){ if active_table_swap().page_fault_handler(pt as *mut InactivePageTable0, addr, false, || alloc_frame().unwrap()){
return true; return true;
} }
}, },
None => { None => {
debug!("get pt from processor()"); info!("get pt from processor()");
let pt = process().get_memory_set_mut().get_page_table_mut(); let pt = process().get_memory_set_mut().get_page_table_mut();
info!("pt got");
if active_table_swap().page_fault_handler(pt as *mut InactivePageTable0, addr, true, || alloc_frame().unwrap()){ if active_table_swap().page_fault_handler(pt as *mut InactivePageTable0, addr, true, || alloc_frame().unwrap()){
return true; return true;
} }

@ -12,7 +12,7 @@ pub mod context;
pub fn init() { pub fn init() {
// NOTE: max_time_slice <= 5 to ensure 'priority' test pass // NOTE: max_time_slice <= 5 to ensure 'priority' test pass
let scheduler = Box::new(scheduler::RRScheduler::new(5)); let scheduler = Box::new(scheduler::RRScheduler::new(5));
let manager = Arc::new(ProcessManager::new(scheduler, MAX_PROCESS_NUM)); let manager = Arc::new(ProcessManager::new(scheduler, MAX_PROCESS_NUM, Process::proc_exit));
extern fn idle(_arg: usize) -> ! { extern fn idle(_arg: usize) -> ! {
loop { cpu::halt(); } loop { cpu::halt(); }

@ -113,8 +113,8 @@ fn sys_yield() -> i32 {
/// Kill the process /// Kill the process
fn sys_kill(pid: usize) -> i32 { fn sys_kill(pid: usize) -> i32 {
info!("kill: {}", pid);
processor().manager().exit(pid, 0x100); processor().manager().exit(pid, 0x100);
Process::proc_exit(pid);
if pid == thread::current().id() { if pid == thread::current().id() {
processor().yield_now(); processor().yield_now();
} }
@ -129,8 +129,8 @@ fn sys_getpid() -> i32 {
/// Exit the current process /// Exit the current process
fn sys_exit(exit_code: usize) -> i32 { fn sys_exit(exit_code: usize) -> i32 {
let pid = thread::current().id(); let pid = thread::current().id();
info!("exit: {}", pid);
processor().manager().exit(pid, exit_code); processor().manager().exit(pid, exit_code);
Process::proc_exit(pid);
processor().yield_now(); processor().yield_now();
unreachable!(); unreachable!();
} }

Loading…
Cancel
Save