Handle backspace for k210/qemu platform && Add lots of user tests.

This commit is contained in:
Yifan Wu 2020-12-11 01:44:07 +08:00
parent f69b3e11dd
commit 48a11e53ff
20 changed files with 361 additions and 35 deletions

29
user/src/bin/exit.rs Normal file
View file

@ -0,0 +1,29 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{fork, yield_, waitpid, exit, wait};
const MAGIC: i32 = -0x10384;
#[no_mangle]
pub fn main() -> i32 {
println!("I am the parent. Forking the child...");
let pid = fork();
if pid == 0 {
println!("I am the child.");
for _ in 0..7 { yield_(); }
exit(MAGIC);
} else {
println!("I am parent, fork a child pid {}", pid);
}
println!("I am the parent, waiting now..");
let mut xstate: i32 = 0;
assert!(waitpid(pid as usize, &mut xstate) == pid && xstate == MAGIC);
assert!(waitpid(pid as usize, &mut xstate) < 0 && wait(&mut xstate) <= 0);
println!("waitpid {} ok.", pid);
println!("exit pass.");
0
}

View file

@ -0,0 +1,44 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
macro_rules! color_text {
($text:expr, $color:expr) => {{
format_args!("\x1b[{}m{}\x1b[0m", $color, $text)
}};
}
#[no_mangle]
pub fn main() -> i32 {
println!(
"{}{}{}{}{} {}{}{}{} {}{}{}{}{}{}",
color_text!("H", 31),
color_text!("e", 32),
color_text!("l", 33),
color_text!("l", 34),
color_text!("o", 35),
color_text!("R", 36),
color_text!("u", 37),
color_text!("s", 90),
color_text!("t", 91),
color_text!("u", 92),
color_text!("C", 93),
color_text!("o", 94),
color_text!("r", 95),
color_text!("e", 96),
color_text!("!", 97),
);
let text =
"reguler \x1b[4munderline\x1b[24m \x1b[7mreverse\x1b[27m \x1b[9mstrikethrough\x1b[29m";
println!("\x1b[47m{}\x1b[0m", color_text!(text, 30));
for i in 31..38 {
println!("{}", color_text!(text, i));
}
for i in 90..98 {
println!("{}", color_text!(text, i));
}
0
}

34
user/src/bin/forktest.rs Normal file
View file

@ -0,0 +1,34 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{fork, wait, exit};
const MAX_CHILD: usize = 20;
#[no_mangle]
pub fn main() -> i32 {
for i in 0..MAX_CHILD {
let pid = fork();
if pid == 0 {
println!("I am child {}", i);
exit(0);
} else {
println!("forked child pid = {}", pid);
}
assert!(pid > 0);
}
let mut exit_code: i32 = 0;
for _ in 0..MAX_CHILD {
if wait(&mut exit_code) <= 0 {
panic!("wait stopped early");
}
}
if wait(&mut exit_code) > 0 {
panic!("wait got too many");
}
println!("forktest pass.");
0
}

35
user/src/bin/forktest2.rs Normal file
View file

@ -0,0 +1,35 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{fork, wait, get_time, getpid, exit, yield_,};
static NUM: usize = 13;
#[no_mangle]
pub fn main() -> i32 {
for _ in 0..NUM {
let pid = fork();
if pid == 0 {
let current_time = get_time();
let sleep_length = (current_time as i32 as isize) * (current_time as i32 as isize) % 1000 + 1000;
println!("Subprocess {} sleep for {} ms", getpid(), sleep_length);
while get_time() < current_time + sleep_length {
yield_();
}
println!("Subprocess {} OK!", getpid());
exit(0);
}
}
let mut xstate: i32 = 0;
for _ in 0..NUM {
assert!(wait(&mut xstate) > 0);
assert_eq!(xstate, 0);
}
assert!(wait(&mut xstate) < 0);
println!("r_forktest2 test passed!");
0
}

View file

@ -0,0 +1,28 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{fork, getpid, wait};
#[no_mangle]
pub fn main() -> i32 {
assert_eq!(wait(&mut 0i32), -1);
println!("sys_wait without child process test passed!");
println!("parent start, pid = {}!", getpid());
let pid = fork();
if pid == 0 {
// child process
println!("hello child process!");
100
} else {
// parent process
let mut xstate: i32 = 0;
println!("ready waiting on parent process!");
assert_eq!(pid, wait(&mut xstate));
assert_eq!(xstate, 100);
println!("child process pid = {}, exit code = {}", pid, xstate);
0
}
}

View file

@ -0,0 +1,11 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
#[no_mangle]
pub fn main() -> i32 {
println!("Hello world from user mode program!");
0
}

View file

@ -4,9 +4,9 @@
#[macro_use]
extern crate user_lib;
use user_lib::{fork, wait, yield_, exit, getpid, get_time, wait_once};
use user_lib::{fork, wait, yield_, exit, getpid, get_time};
static NUM: usize = 13;
static NUM: usize = 20;
const N: usize = 10;
static P: i32 = 10007;
type Arr = [[i32; N]; N];
@ -50,7 +50,7 @@ pub fn main() -> i32 {
if pid == 0 {
let current_time = get_time();
let times = (current_time as i32 as isize) * (current_time as i32 as isize) % 1000;
work(times * 40);
work(times * 10);
}
}
@ -62,7 +62,7 @@ pub fn main() -> i32 {
panic!("wait failed.");
}
}
assert!(wait_once(&mut xstate) < 0);
assert!(wait(&mut xstate) < 0);
println!("matrix passed.");
0
}

30
user/src/bin/sleep.rs Normal file
View file

@ -0,0 +1,30 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{sleep, exit, get_time, fork, waitpid};
fn sleepy() {
let time: usize = 100;
for i in 0..5 {
sleep(time);
println!("sleep {} x {} msecs.", i + 1, time);
}
exit(0);
}
#[no_mangle]
pub fn main() -> i32 {
let current_time = get_time();
let pid = fork();
let mut xstate: i32 = 0;
if pid == 0 {
sleepy();
}
assert!(waitpid(pid as usize, &mut xstate) == pid && xstate == 0);
println!("use {} msecs.", get_time() - current_time);
println!("sleep pass.");
0
}

View file

@ -0,0 +1,19 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{get_time, sleep};
#[no_mangle]
pub fn main() -> i32 {
println!("into sleep test!");
let start = get_time();
println!("current time_msec = {}", start);
sleep(100);
let end = get_time();
println!("time_msec = {} after sleeping 100 ticks, delta = {}ms!", end, end - start);
println!("r_sleep passed!");
0
}

View file

@ -0,0 +1,17 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
fn f(d: usize) {
println!("d = {}",d);
f(d + 1);
}
#[no_mangle]
pub fn main() -> i32 {
println!("It should trigger segmentation fault!");
f(0);
0
}

View file

@ -53,7 +53,7 @@ pub fn main() -> i32 {
}
print!(">> ");
}
DL => {
BS | DL => {
if !line.is_empty() {
print!("{}", BS as char);
print!(" ");

40
user/src/bin/usertests.rs Normal file
View file

@ -0,0 +1,40 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
static TESTS: &[&str] = &[
"exit\0",
"fantastic_text\0",
"forktest\0",
"forktest2\0",
"forktest_simple\0",
"hello_world\0",
"matrix\0",
"sleep\0",
"sleep_simple\0",
"stack_overflow\0",
"yield\0",
];
use user_lib::{exec, fork, waitpid};
#[no_mangle]
pub fn main() -> i32 {
for test in TESTS {
println!("Usertests: Running {}", test);
let pid = fork();
if pid == 0 {
exec(*test);
panic!("unreachable!");
} else {
let mut xstate: i32 = Default::default();
let wait_pid = waitpid(pid as usize, &mut xstate);
assert_eq!(pid, wait_pid);
println!("\x1b[32mUsertests: Test {} in Process {} exited with code {}\x1b[0m", test, pid, xstate);
}
}
println!("Usertests passed!");
0
}

17
user/src/bin/yield.rs Normal file
View file

@ -0,0 +1,17 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{getpid, yield_};
#[no_mangle]
pub fn main() -> i32 {
println!("Hello, I am process {}.", getpid());
for i in 0..5 {
yield_();
println!("Back in process {}, iteration {}.", getpid(), i);
}
println!("yield pass.");
0
}

View file

@ -51,19 +51,25 @@ pub fn exec(path: &str) -> isize { sys_exec(path) }
pub fn wait(exit_code: &mut i32) -> isize {
loop {
match sys_waitpid(-1, exit_code as *mut _) {
-1 => { yield_(); }
-2 => { yield_(); }
// -1 or a real pid
exit_pid => return exit_pid,
}
}
}
pub fn wait_once(exit_code: &mut i32) -> isize {
sys_waitpid(-1, exit_code as *mut _)
}
pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize {
loop {
match sys_waitpid(pid as isize, exit_code as *mut _) {
-1 => { yield_(); }
-2 => { yield_(); }
// -1 or a real pid
exit_pid => return exit_pid,
}
}
}
pub fn sleep(period_ms: usize) {
let start = sys_get_time();
while sys_get_time() < start + period_ms as isize {
sys_yield();
}
}