mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-26 03:13:36 +04:00
forktree worked with depth=3 on k210 platform.
This commit is contained in:
parent
244c0ee84d
commit
84b10893d4
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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
37
user/src/bin/forktree.rs
Normal 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
|
||||||
|
}
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user