forktree worked with depth=3 on k210 platform.

This commit is contained in:
Yifan Wu 2020-12-11 16:14:14 +08:00
parent 244c0ee84d
commit 84b10893d4
6 changed files with 62 additions and 17 deletions

View File

@ -212,7 +212,7 @@ impl MemorySet {
pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> { pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
self.page_table.translate(vpn) self.page_table.translate(vpn)
} }
pub fn clear(&mut self) { pub fn recycle_data_pages(&mut self) {
//*self = Self::new_bare(); //*self = Self::new_bare();
self.areas.clear(); self.areas.clear();
} }

View File

@ -1,5 +1,5 @@
use crate::mm::translated_byte_buffer; use crate::mm::translated_byte_buffer;
use crate::task::{current_user_token}; use crate::task::{current_user_token, suspend_current_and_run_next};
use crate::sbi::console_getchar; use crate::sbi::console_getchar;
const FD_STDIN: usize = 0; const FD_STDIN: usize = 0;
@ -28,7 +28,7 @@ pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
loop { loop {
c = console_getchar(); c = console_getchar();
if c == 0 { if c == 0 {
//suspend_current_and_run_next(); suspend_current_and_run_next();
continue; continue;
} else { } else {
break; break;

View File

@ -10,6 +10,7 @@ use switch::__switch;
use task::{TaskControlBlock, TaskStatus}; use task::{TaskControlBlock, TaskStatus};
use alloc::sync::Arc; use alloc::sync::Arc;
use manager::fetch_task; use manager::fetch_task;
use lazy_static::*;
pub use context::TaskContext; pub use context::TaskContext;
pub use processor::{ pub use processor::{
@ -51,22 +52,20 @@ pub fn exit_current_and_run_next(exit_code: i32) {
inner.task_status = TaskStatus::Zombie; inner.task_status = TaskStatus::Zombie;
// Record exit code // Record exit code
inner.exit_code = exit_code; inner.exit_code = exit_code;
// move any child to its parent // do not move to its parent but under initproc
// TODO: do not move to its parent but under initproc
// ++++++ hold parent PCB lock here // ++++++ hold initproc PCB lock here
{ {
let parent = inner.parent.as_ref().unwrap().upgrade().unwrap(); let mut initproc_inner = INITPROC.acquire_inner_lock();
let mut parent_inner = parent.acquire_inner_lock();
for child in inner.children.iter() { for child in inner.children.iter() {
parent_inner.children.push(child.clone()); initproc_inner.children.push(child.clone());
} }
} }
// ++++++ release parent PCB lock here // ++++++ release parent PCB lock here
inner.children.clear(); inner.children.clear();
// deallocate user space // deallocate user space
inner.memory_set.clear(); inner.memory_set.recycle_data_pages();
drop(inner); drop(inner);
// **** release current PCB lock // **** release current PCB lock
// drop task manually to maintain rc correctly // drop task manually to maintain rc correctly
@ -76,7 +75,12 @@ pub fn exit_current_and_run_next(exit_code: i32) {
schedule(&_unused as *const _); schedule(&_unused as *const _);
} }
pub fn add_initproc() { lazy_static! {
let data = get_app_data_by_name("initproc").unwrap(); pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new(
add_task(Arc::new(TaskControlBlock::new(data))); TaskControlBlock::new(get_app_data_by_name("initproc").unwrap())
);
}
pub fn add_initproc() {
add_task(INITPROC.clone());
} }

View File

@ -30,6 +30,6 @@ pub fn main() -> i32 {
assert_eq!(xstate, 0); assert_eq!(xstate, 0);
} }
assert!(wait(&mut xstate) < 0); assert!(wait(&mut xstate) < 0);
println!("r_forktest2 test passed!"); println!("forktest2 test passed!");
0 0
} }

37
user/src/bin/forktree.rs Normal file
View File

@ -0,0 +1,37 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{sleep, getpid, fork, exit, yield_};
const DEPTH: usize = 3;
fn fork_child(cur: &str, branch: char) {
let mut next = [0u8; DEPTH + 1];
let l = cur.len();
if l >= DEPTH {
return;
}
&mut next[..l].copy_from_slice(cur.as_bytes());
next[l] = branch as u8;
if fork() == 0 {
fork_tree(core::str::from_utf8(&next[..l + 1]).unwrap());
yield_();
exit(0);
}
}
fn fork_tree(cur: &str) {
println!("pid{}: {}", getpid(), cur);
fork_child(cur, '0');
fork_child(cur, '1');
}
#[no_mangle]
pub fn main() -> i32 {
fork_tree("");
sleep(3000);
0
}

View File

@ -17,13 +17,17 @@ fn main() -> i32 {
exec("user_shell\0"); exec("user_shell\0");
} else { } else {
loop { loop {
let mut xstatus: i32 = 0; let mut exit_code: i32 = 0;
let pid = wait(&mut xstatus); let pid = wait(&mut exit_code);
if pid == -1 { if pid == -1 {
yield_(); yield_();
continue; continue;
} }
println!("[initproc] Release a zombie process!"); println!(
"[initproc] Released a zombie process, pid={}, exit_code={}",
pid,
exit_code,
);
} }
} }
0 0