Code transplanting: Fix bugs. Pass test 'spin'

master
lcy1996 6 years ago
parent 4a92a4c6a1
commit 9adcea44d5

@ -288,7 +288,8 @@ impl<T: PageTable, M: SwapManager, S: Swapper> SwapExt<T, M, S> {
//info!("got entry!");
!entry.present() && !entry.swapped()
};
if need_alloc{
info!("need_alloc got");
if need_alloc {
info!("need_alloc!");
let frame = alloc_frame();
{
@ -307,6 +308,7 @@ impl<T: PageTable, M: SwapManager, S: Swapper> SwapExt<T, M, S> {
info!("allocated successfully");
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
if !self.page_table.get_entry(addr).swapped() {

@ -39,23 +39,17 @@ pub struct ProcessManager {
scheduler: Mutex<Box<Scheduler>>,
wait_queue: Vec<Mutex<Vec<Pid>>>,
event_hub: Mutex<EventHub<Event>>,
exit_handler: fn(Pid),
}
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 {
procs: {
let mut vec = Vec::new();
vec.resize_default(max_proc_num);
vec
},
procs: new_vec_default(max_proc_num),
scheduler: Mutex::new(scheduler),
wait_queue: {
let mut vec = Vec::new();
vec.resize_default(max_proc_num);
vec
},
wait_queue: new_vec_default(max_proc_num),
event_hub: Mutex::new(EventHub::new()),
exit_handler,
}
}
@ -124,7 +118,7 @@ impl ProcessManager {
proc.context = Some(context);
match proc.status {
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,
}
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) {
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(..) {
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");
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()
.position(|x| unsafe{(*(x.clone() as *mut MemorySet)).get_page_table_mut().token() == ActivePageTable::token()});
info!("id got");
let mut mmsets = memory_set_record();
info!("mmset got");
match id {
Some(targetid) => {
debug!("get id from memroy set recorder.");
info!("get id from memroy set recorder.");
let mmset_ptr = mmsets.get(targetid);
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()){
return true;
}
},
None => {
debug!("get pt from processor()");
info!("get pt from processor()");
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()){
return true;
}

@ -12,7 +12,7 @@ pub mod context;
pub fn init() {
// NOTE: max_time_slice <= 5 to ensure 'priority' test pass
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) -> ! {
loop { cpu::halt(); }

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

Loading…
Cancel
Save