diff --git a/ch5/user/src/bin/02sleep.rs b/ch5/user/src/bin/02sleep.rs index 15bafda..ebba65a 100644 --- a/ch5/user/src/bin/02sleep.rs +++ b/ch5/user/src/bin/02sleep.rs @@ -1,6 +1,9 @@ #![no_std] #![no_main] +extern crate alloc; + +use alloc::vec::Vec; use user_lib::*; use user_lib::syscall::*; diff --git a/ch5/user/src/bin/forktest_simple.rs b/ch5/user/src/bin/forktest_simple.rs new file mode 100644 index 0000000..e086549 --- /dev/null +++ b/ch5/user/src/bin/forktest_simple.rs @@ -0,0 +1,29 @@ +#![no_std] +#![no_main] + + + +use user_lib::*; +use syscall::{sys_fork, }; +use user_lib::syscall::sys_getpid; + +#[no_mangle] +pub fn main() -> i32 { + assert_eq!(wait(&mut 0i32), -1); + println!("sys_wait without child process test passed!"); + println!("parent start, pid = {}!", sys_getpid()); + let pid = sys_fork(); + if pid == 0 { + // child process + println!("hello child process!"); + 100 + } else { + // parent process + let mut exit_code: i32 = 0; + println!("ready waiting on parent process!"); + assert_eq!(pid, wait(&mut exit_code)); + assert_eq!(exit_code, 100); + println!("child process pid = {}, exit code = {}", pid, exit_code); + 0 + } +} diff --git a/ch5/user/src/bin/forktree.rs b/ch5/user/src/bin/forktree.rs new file mode 100644 index 0000000..c056646 --- /dev/null +++ b/ch5/user/src/bin/forktree.rs @@ -0,0 +1,36 @@ +#![no_std] +#![no_main] + +use user_lib::*; +use syscall::{sys_fork, sys_getpid, sys_yield}; +use user_lib::syscall::sys_exit; + +const DEPTH: usize = 4; + +fn fork_child(cur: &str, branch: char) { + let mut next = [0u8; DEPTH + 1]; + let l = cur.len(); + if l >= DEPTH { + return; + } + next[..l].copy_from_slice(cur.as_bytes()); + next[l] = branch as u8; + if sys_fork() == 0 { + fork_tree(core::str::from_utf8(&next[..l + 1]).unwrap()); + sys_yield(); + sys_exit(0); + } +} + +fn fork_tree(cur: &str) { + println!("pid{}: {}", sys_getpid(), cur); + fork_child(cur, '0'); + fork_child(cur, '1'); +} + +#[no_mangle] +pub fn main() -> i32 { + fork_tree(""); + sleep(3000); + 0 +} diff --git a/ch5/user/src/bin/matrix.rs b/ch5/user/src/bin/matrix.rs new file mode 100644 index 0000000..cbb5e6e --- /dev/null +++ b/ch5/user/src/bin/matrix.rs @@ -0,0 +1,70 @@ +#![no_std] +#![no_main] +#![allow(clippy::needless_range_loop)] + +use user_lib::*; +use syscall::{sys_fork, sys_getpid, sys_yield}; +use user_lib::syscall::{sys_exit, sys_get_time}; + + +static NUM: usize = 30; +const N: usize = 10; +static P: i32 = 10007; +type Arr = [[i32; N]; N]; + +fn work(times: isize) { + let mut a: Arr = Default::default(); + let mut b: Arr = Default::default(); + let mut c: Arr = Default::default(); + for i in 0..N { + for j in 0..N { + a[i][j] = 1; + b[i][j] = 1; + } + } + sys_yield(); + println!("pid {} is running ({} times)!.", sys_getpid(), times); + for _ in 0..times { + for i in 0..N { + for j in 0..N { + c[i][j] = 0; + #[allow(clippy::needless_range_loop)] + for k in 0..N { + c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % P; + } + } + } + for i in 0..N { + for j in 0..N { + a[i][j] = c[i][j]; + b[i][j] = c[i][j]; + } + } + } + println!("pid {} done!.", sys_getpid()); + sys_exit(0); +} + +#[no_mangle] +pub fn main() -> i32 { + for _ in 0..NUM { + let pid = sys_fork(); + if pid == 0 { + let current_time = sys_get_time(); + let times = (current_time as i32 as isize) * (current_time as i32 as isize) % 1000; + work(times * 10); + } + } + + println!("fork ok."); + + let mut exit_code: i32 = 0; + for _ in 0..NUM { + if wait(&mut exit_code) < 0 { + panic!("wait failed."); + } + } + assert!(wait(&mut exit_code) < 0); + println!("matrix passed."); + 0 +} diff --git a/ch5/user/src/lib.rs b/ch5/user/src/lib.rs index bf4305a..bacb81b 100644 --- a/ch5/user/src/lib.rs +++ b/ch5/user/src/lib.rs @@ -65,3 +65,10 @@ pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize { } } } + +pub fn sleep(period_ms: usize) { + let start = sys_get_time(); + while sys_get_time() < start + period_ms as isize { + sys_yield(); + } +} \ No newline at end of file