Yield. Shorter schedule interval.

master
WangRunji 7 years ago
parent 601d0f85bd
commit 4e35b927d2

@ -152,6 +152,8 @@ impl ActivePageTable {
unsafe {
control_regs::cr3_write(new_table.p4_frame.start_address());
}
use core::mem::forget;
forget(new_table);
old_table
}
}
@ -176,4 +178,10 @@ impl InactivePageTable {
InactivePageTable { p4_frame: frame }
}
}
impl Drop for InactivePageTable {
fn drop(&mut self) {
warn!("PageTable dropped: {:?}", self);
}
}

@ -10,8 +10,8 @@ extern fn eh_personality() {
#[lang = "panic_fmt"]
#[no_mangle]
pub extern fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) -> ! {
println!("\n\nPANIC in {} at line {}:", file, line);
println!(" {}", fmt);
error!("\n\nPANIC in {} at line {}:", file, line);
error!(" {}", fmt);
if cfg!(feature = "qemu_auto_exit") {
unsafe{ cpu::exit_in_qemu(3) }
} else {

@ -105,7 +105,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! {
loop{
println!("init ...");
let mut i = 0;
while i < 1 << 23 {
while i < 1 << 22 {
i += 1;
}
}

@ -87,10 +87,10 @@ pub fn remap_the_kernel(boot_info: BootInformation) -> Stack {
let mut page_table = InactivePageTable::new(alloc_frame(), &mut active_table);
active_table.with(&mut page_table, |pt| memory_set.map(pt));
println!("{:#x?}", memory_set);
debug!("{:#x?}", memory_set);
let old_table = active_table.switch(page_table);
println!("NEW TABLE!!!");
info!("NEW TABLE!!!");
// turn the stack bottom into a guard page
extern { fn stack_bottom(); }
@ -98,7 +98,7 @@ pub fn remap_the_kernel(boot_info: BootInformation) -> Stack {
let stack_bottom_page = Page::of_addr(stack_bottom);
active_table.unmap(stack_bottom_page);
let kernel_stack = Stack::new(stack_bottom + 8 * PAGE_SIZE, stack_bottom + 1 * PAGE_SIZE);
println!("guard page at {:#x}", stack_bottom_page.start_address());
debug!("guard page at {:#x}", stack_bottom_page.start_address());
kernel_stack
}

@ -84,6 +84,6 @@ impl Stack {
impl Drop for Stack {
fn drop(&mut self) {
warn!("stack leak: {:#x?}", self);
warn!("stack leak: {:x?}", self);
}
}

@ -35,7 +35,7 @@ extern fn idle_thread() {
loop {
println!("idle ...");
let mut i = 0;
while i < 1 << 23 {
while i < 1 << 22 {
i += 1;
}
}
@ -51,23 +51,36 @@ pub fn sys_fork(tf: &TrapFrame) -> i32 {
pid as i32
}
/// Wait the process exit. Return the exit code.
pub fn sys_wait(rsp: &mut usize, pid: usize) -> 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(error_code) => error_code as i32,
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 }
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);

@ -21,7 +21,7 @@ impl Processor {
current_pid: 0,
event_hub: {
let mut e = EventHub::new();
e.push(100, Event::Schedule);
e.push(10, Event::Schedule);
e
},
kernel_page_table: None,
@ -48,7 +48,7 @@ impl Processor {
debug!("Processor: event {:?}", event);
match event {
Event::Schedule => {
self.event_hub.push(100, Event::Schedule);
self.event_hub.push(10, Event::Schedule);
self.schedule(rsp);
},
Event::Wakeup(pid) => {
@ -78,7 +78,7 @@ impl Processor {
fn find_next(&self) -> Pid {
*self.procs.keys()
.find(|&&i| i > self.current_pid
&& self.get(i).exit_code().is_none())
&& self.get(i).status == Status::Ready)
.unwrap_or(self.procs.keys().next().unwrap())
}
@ -162,6 +162,7 @@ impl Processor {
/// Let current process wait for another
pub fn current_wait_for(&mut self, target: WaitTarget) -> WaitResult {
info!("Processor: current {} wait for {:?}", self.current_pid, target);
// Find one target process and it's exit code
let (pid, exit_code) = match target {
WaitTarget::AnyChild => {
@ -180,7 +181,7 @@ impl Processor {
if let Some(exit_code) = exit_code {
info!("Processor: {} wait find and remove {}", self.current_pid, pid);
self.procs.remove(&pid);
WaitResult::Ok(exit_code)
WaitResult::Ok(pid, exit_code)
} else {
info!("Processor: {} wait for {}", self.current_pid, pid);
let current_pid = self.current_pid;
@ -205,17 +206,19 @@ impl Debug for Processor {
}
}
#[derive(Debug)]
pub enum WaitTarget {
AnyChild,
Proc(Pid),
}
#[derive(Debug)]
pub enum WaitResult {
/// The target process is still running.
/// The waiter's status will be set to `Waiting`.
Blocked,
/// The target process is exited with `ErrorCode`.
Ok(ErrorCode),
Ok(Pid, ErrorCode),
/// The target process is not exist.
NotExist,
}

@ -22,13 +22,15 @@ pub unsafe fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 {
Syscall::Xv6(SYS_CLOSE) | Syscall::Ucore(UCORE_SYS_CLOSE) =>
io::close(args[0]),
Syscall::Xv6(SYS_WAIT) | Syscall::Ucore(UCORE_SYS_WAIT) =>
process::sys_wait(rsp, args[0]),
process::sys_wait(rsp, args[0], args[1] as *mut i32),
Syscall::Xv6(SYS_FORK) | Syscall::Ucore(UCORE_SYS_FORK) =>
process::sys_fork(tf),
Syscall::Xv6(SYS_KILL) | Syscall::Ucore(UCORE_SYS_KILL) =>
process::sys_kill(args[0]),
Syscall::Xv6(SYS_EXIT) | Syscall::Ucore(UCORE_SYS_EXIT) =>
process::sys_exit(rsp, args[0]),
Syscall::Ucore(UCORE_SYS_YIELD) =>
process::sys_yield(rsp),
Syscall::Ucore(UCORE_SYS_GETPID) =>
process::sys_getpid(),
Syscall::Ucore(UCORE_SYS_SLEEP) =>

@ -0,0 +1,22 @@
## uCore 32bit user programs pass status
- [ ] badarg
- [ ] badsegment
- [ ] divzero
- [ ] exit
- [ ] faultread
- [ ] faultreadkernel
- [x] forktest
- [x] forktree
- [x] hello
- [ ] ls
- [x] matrix
- [ ] pgdir
- [ ] priority
- [ ] sh
- [ ] sleep
- [x] sleepkill
- [ ] softint
- [x] spin
- [ ] testbss
- [x] waitkill
- [x] yield
Loading…
Cancel
Save