commit
8f0fcfaf5e
@ -1,10 +1,7 @@
|
||||
.idea/*
|
||||
os/target/*
|
||||
os/.idea/*
|
||||
.idea
|
||||
Cargo.lock
|
||||
target
|
||||
os/src/link_app.S
|
||||
os/last-*
|
||||
os/Cargo.lock
|
||||
user/target/*
|
||||
user/.idea/*
|
||||
user/Cargo.lock
|
||||
tools/
|
||||
user/build
|
||||
tools
|
||||
|
@ -0,0 +1,34 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
extern crate alloc;
|
||||
|
||||
use user_lib::{
|
||||
open,
|
||||
OpenFlags,
|
||||
close,
|
||||
read,
|
||||
};
|
||||
use alloc::string::String;
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main(argc: usize, argv: &[&str]) -> i32 {
|
||||
assert!(argc == 2);
|
||||
let fd = open(argv[1], OpenFlags::RDONLY);
|
||||
if fd == -1 {
|
||||
panic!("Error occured when opening file");
|
||||
}
|
||||
let fd = fd as usize;
|
||||
let mut buf = [0u8; 16];
|
||||
let mut s = String::new();
|
||||
loop {
|
||||
let size = read(fd, &mut buf) as usize;
|
||||
if size == 0 { break; }
|
||||
s.push_str(core::str::from_utf8(&buf[..size]).unwrap());
|
||||
}
|
||||
println!("{}", s);
|
||||
close(fd);
|
||||
0
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{
|
||||
open,
|
||||
close,
|
||||
read,
|
||||
write,
|
||||
OpenFlags,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
let test_str = "Hello, world!";
|
||||
let filea = "filea\0";
|
||||
let fd = open(filea, OpenFlags::CREATE | OpenFlags::WRONLY);
|
||||
assert!(fd > 0);
|
||||
let fd = fd as usize;
|
||||
write(fd, test_str.as_bytes());
|
||||
close(fd);
|
||||
|
||||
let fd = open(filea, OpenFlags::RDONLY);
|
||||
assert!(fd > 0);
|
||||
let fd = fd as usize;
|
||||
let mut buffer = [0u8; 100];
|
||||
let read_len = read(fd, &mut buffer) as usize;
|
||||
close(fd);
|
||||
|
||||
assert_eq!(
|
||||
test_str,
|
||||
core::str::from_utf8(&buffer[..read_len]).unwrap(),
|
||||
);
|
||||
println!("file_test passed!");
|
||||
0
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{
|
||||
OpenFlags,
|
||||
open,
|
||||
close,
|
||||
write,
|
||||
get_time,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
let mut buffer = [0u8; 1024]; // 1KiB
|
||||
for i in 0..buffer.len() {
|
||||
buffer[i] = i as u8;
|
||||
}
|
||||
let f = open("testf", OpenFlags::CREATE | OpenFlags::WRONLY);
|
||||
if f < 0 {
|
||||
panic!("Open test file failed!");
|
||||
}
|
||||
let f = f as usize;
|
||||
let start = get_time();
|
||||
let size_mb = 1usize;
|
||||
for _ in 0..1024*size_mb {
|
||||
write(f, &buffer);
|
||||
}
|
||||
close(f);
|
||||
let time_ms = (get_time() - start) as usize;
|
||||
let speed_kbs = size_mb * 1000000 / time_ms;
|
||||
println!("time cost = {}ms, write speed = {}KiB/s", time_ms, speed_kbs);
|
||||
0
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::getpid;
|
||||
|
||||
/*
|
||||
辅助测例 打印子进程 pid
|
||||
*/
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
let pid = getpid();
|
||||
println!("Test getpid OK! pid = {}", pid);
|
||||
0
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{getpid, mail_read, mail_write};
|
||||
|
||||
const BUF_LEN: usize = 256;
|
||||
const MAIL_MAX: usize = 16;
|
||||
|
||||
/// 测试邮箱容量,输出 mail1 test OK! 就算正确。
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
let pid = getpid();
|
||||
let buffer0 = ['a' as u8; BUF_LEN];
|
||||
for _ in 0..MAIL_MAX {
|
||||
assert_eq!(mail_write(pid as usize, &buffer0), BUF_LEN as isize);
|
||||
}
|
||||
assert_eq!(mail_write(pid as usize, &buffer0), -1);
|
||||
let mut buf = [0u8; BUF_LEN];
|
||||
assert_eq!(mail_read(&mut buf), BUF_LEN as isize);
|
||||
assert_eq!(mail_write(pid as usize, &buffer0), BUF_LEN as isize);
|
||||
assert_eq!(mail_write(pid as usize, &buffer0), -1);
|
||||
println!("mail1 test OK!");
|
||||
0
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{exit, fork, mail_read, mail_write, sleep, wait};
|
||||
|
||||
const BUF_LEN: usize = 256;
|
||||
|
||||
// 双进程邮箱测试,最终输出 mail2 test OK! 就算正确。
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
let pid = fork();
|
||||
if pid == 0 {
|
||||
println!("I am child");
|
||||
let mut buffer = [0u8; BUF_LEN];
|
||||
assert_eq!(mail_read(&mut buffer), -1);
|
||||
println!("child read 1 mail fail");
|
||||
println!("child sleep 2s");
|
||||
sleep(2000 as usize);
|
||||
for i in 0..16 {
|
||||
let mut buffer = [0u8; BUF_LEN];
|
||||
assert_eq!(mail_read(&mut buffer), BUF_LEN as isize);
|
||||
assert_eq!(buffer, [i as u8; BUF_LEN]);
|
||||
}
|
||||
println!("child read 16 mails succeed");
|
||||
assert_eq!(mail_read(&mut buffer), -1);
|
||||
println!("child read 1 mail fail");
|
||||
println!("child sleep 1s");
|
||||
sleep(1000 as usize);
|
||||
assert_eq!(mail_read(&mut buffer), BUF_LEN as isize);
|
||||
assert_eq!(buffer, [16 as u8; BUF_LEN]);
|
||||
println!("child read 1 mail succeed");
|
||||
println!("child exit");
|
||||
exit(0);
|
||||
}
|
||||
println!("I am father");
|
||||
println!("father sleep 1s");
|
||||
sleep(1000 as usize);
|
||||
for i in 0..16 {
|
||||
let buffer = [i as u8; BUF_LEN];
|
||||
assert_eq!(mail_write(pid as usize, &buffer), BUF_LEN as isize);
|
||||
}
|
||||
println!("father wirte 16 mails succeed");
|
||||
let buffer = [16 as u8; BUF_LEN];
|
||||
assert_eq!(mail_write(pid as usize, &buffer), -1);
|
||||
println!("father wirte 1 mail fail");
|
||||
println!("father sleep 1.5s");
|
||||
sleep(1500 as usize);
|
||||
assert_eq!(mail_write(pid as usize, &buffer), BUF_LEN as isize);
|
||||
println!("father wirte 1 mail succeed");
|
||||
|
||||
let mut xstate: i32 = -100;
|
||||
assert!(wait(&mut xstate) > 0);
|
||||
assert_eq!(xstate, 0);
|
||||
println!("mail2 test OK!");
|
||||
0
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate core;
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use core::slice;
|
||||
use user_lib::{getpid, mail_read, mail_write};
|
||||
|
||||
const BUF_LEN: usize = 256;
|
||||
const MAIL_MAX: usize = 16;
|
||||
const BAD_ADDRESS: usize = 0x90000000;
|
||||
|
||||
/// 邮箱错误参数测试,输出 mail3 test OK! 就算正确。
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
let pid = getpid();
|
||||
let null = unsafe { slice::from_raw_parts(BAD_ADDRESS as *const _, 10) };
|
||||
assert_eq!(mail_write(pid as usize, &null), -1);
|
||||
let mut empty = ['a' as u8; 0];
|
||||
assert_eq!(mail_write(pid as usize, &empty), 0);
|
||||
assert_eq!(mail_read(&mut empty), -1);
|
||||
let buffer0 = ['a' as u8; BUF_LEN];
|
||||
for _ in 0..MAIL_MAX {
|
||||
assert_eq!(mail_write(pid as usize, &buffer0), BUF_LEN as isize);
|
||||
}
|
||||
assert_eq!(mail_write(pid as usize, &empty), -1);
|
||||
assert_eq!(mail_read(&mut empty), 0);
|
||||
assert_eq!(mail_write(pid as usize, &empty), -1);
|
||||
println!("mail3 test OK!");
|
||||
0
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{get_time, yield_};
|
||||
|
||||
/// 正确输出:(无报错信息)
|
||||
/// get_time OK! {...}
|
||||
/// Test sleep OK!
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
let current_time = get_time();
|
||||
assert!(current_time > 0);
|
||||
println!("get_time OK! {}", current_time);
|
||||
let wait_for = current_time + 3000;
|
||||
while get_time() < wait_for {
|
||||
yield_();
|
||||
}
|
||||
println!("Test sleep OK!");
|
||||
0
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{get_time, sleep};
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
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!("Test sleep1 passed!");
|
||||
0
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{spawn, wait, waitpid};
|
||||
|
||||
/// 程序行为:先后产生 3 个有特定返回值的程序,检查 waitpid 能够获取正确返回值。
|
||||
|
||||
/// 理想输出:
|
||||
/// new child i
|
||||
/// Test wait OK!
|
||||
/// Test waitpid OK!
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
let cpid = spawn("test_exit0\0");
|
||||
assert!(cpid >= 0, "child pid invalid");
|
||||
println!("new child {}", cpid);
|
||||
let mut exit_code: i32 = 0;
|
||||
let exit_pid = wait(&mut exit_code);
|
||||
assert_eq!(exit_pid, cpid, "error exit pid");
|
||||
assert_eq!(exit_code, 66778, "error exit code");
|
||||
println!("Test wait OK!");
|
||||
let (cpid0, cpid1) = (spawn("test_exit0\0"), spawn("test_exit1\0"));
|
||||
let exit_pid = waitpid(cpid1 as usize, &mut exit_code);
|
||||
assert_eq!(exit_pid, cpid1, "error exit pid");
|
||||
assert_eq!(exit_code, -233, "error exit code");
|
||||
let exit_pid = wait(&mut exit_code);
|
||||
assert_eq!(exit_pid, cpid0, "error exit pid");
|
||||
assert_eq!(exit_code, 66778, "error exit code");
|
||||
println!("Test waitpid OK!");
|
||||
0
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
static TESTS: &[&str] = &[
|
||||
"test_sleep\0",
|
||||
"test_sleep1\0",
|
||||
"test_mmap0\0",
|
||||
"test_mmap1\0",
|
||||
"test_mmap2\0",
|
||||
"test_mmap3\0",
|
||||
"test_unmap\0",
|
||||
"test_unmap2\0",
|
||||
"test_spawn0\0",
|
||||
"test_spawn1\0",
|
||||
"test_mail0\0",
|
||||
"test_mail1\0",
|
||||
"test_mail2\0",
|
||||
"test_mail3\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 exit_code: i32 = Default::default();
|
||||
let wait_pid = waitpid(pid as usize, &mut exit_code);
|
||||
assert_eq!(pid, wait_pid);
|
||||
println!(
|
||||
"\x1b[32mUsertests: Test {} in Process {} exited with code {}\x1b[0m",
|
||||
test, pid, exit_code
|
||||
);
|
||||
}
|
||||
}
|
||||
println!("ch6 Usertests passed!");
|
||||
0
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
use user_lib::{write, STDOUT};
|
||||
const DATA_STRING: &str = "string from data section\n";
|
||||
|
||||
/// 正确输出:
|
||||
/// string from data section
|
||||
/// strinstring from stack section
|
||||
/// strin
|
||||
/// Test write1 OK!
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
assert_eq!(write(1234, DATA_STRING.as_bytes()), -1);
|
||||
assert_eq!(
|
||||
write(STDOUT, DATA_STRING.as_bytes()),
|
||||
DATA_STRING.len() as isize
|
||||
);
|
||||
assert_eq!(write(STDOUT, &DATA_STRING.as_bytes()[..5]), 5);
|
||||
let stack_string = "string from stack section\n";
|
||||
assert_eq!(
|
||||
write(STDOUT, stack_string.as_bytes()),
|
||||
stack_string.len() as isize
|
||||
);
|
||||
assert_eq!(write(STDOUT, &stack_string.as_bytes()[..5]), 5);
|
||||
println!("\nTest write1 OK!");
|
||||
0
|
||||
}
|
Loading…
Reference in new issue