Pipe OK.
This commit is contained in:
parent
e93a4a0b76
commit
2d34cab989
14 changed files with 218 additions and 18 deletions
69
user/src/bin/pipe_large_test.rs
Normal file
69
user/src/bin/pipe_large_test.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use user_lib::{fork, close, pipe, read, write, wait, get_time};
|
||||
use alloc::format;
|
||||
|
||||
const LENGTH: usize = 3000;
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
// create pipes
|
||||
// parent write to child
|
||||
let mut down_pipe_fd = [0usize; 2];
|
||||
// child write to parent
|
||||
let mut up_pipe_fd = [0usize; 2];
|
||||
pipe(&mut down_pipe_fd);
|
||||
pipe(&mut up_pipe_fd);
|
||||
let mut random_str = [0u8; LENGTH];
|
||||
if fork() == 0 {
|
||||
// close write end of down pipe
|
||||
close(down_pipe_fd[1]);
|
||||
// close read end of up pipe
|
||||
close(up_pipe_fd[0]);
|
||||
assert_eq!(read(down_pipe_fd[0], &mut random_str) as usize, LENGTH);
|
||||
close(down_pipe_fd[0]);
|
||||
let sum: usize = random_str.iter().map(|v| *v as usize).sum::<usize>();
|
||||
println!("sum = {}(child)", sum);
|
||||
let sum_str = format!("{}", sum);
|
||||
write(up_pipe_fd[1], sum_str.as_bytes());
|
||||
close(up_pipe_fd[1]);
|
||||
println!("Child process exited!");
|
||||
0
|
||||
} else {
|
||||
// close read end of down pipe
|
||||
close(down_pipe_fd[0]);
|
||||
// close write end of up pipe
|
||||
close(up_pipe_fd[1]);
|
||||
// generate a long random string
|
||||
for i in 0..LENGTH {
|
||||
random_str[i] = get_time() as u8;
|
||||
}
|
||||
// send it
|
||||
assert_eq!(write(down_pipe_fd[1], &random_str) as usize, random_str.len());
|
||||
// close write end of down pipe
|
||||
close(down_pipe_fd[1]);
|
||||
// calculate sum(parent)
|
||||
let sum: usize = random_str.iter().map(|v| *v as usize).sum::<usize>();
|
||||
println!("sum = {}(parent)", sum);
|
||||
// recv sum(child)
|
||||
let mut child_result = [0u8; 32];
|
||||
let result_len = read(up_pipe_fd[0], &mut child_result) as usize;
|
||||
close(up_pipe_fd[0]);
|
||||
// check
|
||||
assert_eq!(
|
||||
sum,
|
||||
str::parse::<usize>(
|
||||
core::str::from_utf8(&child_result[..result_len]).unwrap()
|
||||
).unwrap()
|
||||
);
|
||||
let mut _unused: i32 = 0;
|
||||
wait(&mut _unused);
|
||||
println!("pipe_large_test passed!");
|
||||
0
|
||||
}
|
||||
}
|
42
user/src/bin/pipetest.rs
Normal file
42
user/src/bin/pipetest.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{fork, close, pipe, read, write, wait};
|
||||
|
||||
static STR: &str = "Hello, world!";
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
// create pipe
|
||||
let mut pipe_fd = [0usize; 2];
|
||||
pipe(&mut pipe_fd);
|
||||
// read end
|
||||
assert_eq!(pipe_fd[0], 3);
|
||||
// write end
|
||||
assert_eq!(pipe_fd[1], 4);
|
||||
if fork() == 0 {
|
||||
// child process, read from parent
|
||||
// close write_end
|
||||
close(pipe_fd[1]);
|
||||
let mut buffer = [0u8; 32];
|
||||
let len_read = read(pipe_fd[0], &mut buffer) as usize;
|
||||
assert_eq!(core::str::from_utf8(&buffer[..len_read]).unwrap(), STR);
|
||||
println!("Read OK, child process exited!");
|
||||
0
|
||||
} else {
|
||||
// parent process, write to child
|
||||
// close read end
|
||||
close(pipe_fd[0]);
|
||||
assert_eq!(write(pipe_fd[1], STR.as_bytes()), STR.len() as isize);
|
||||
// close write end
|
||||
close(pipe_fd[1]);
|
||||
let mut child_exit_code: i32 = 0;
|
||||
wait(&mut child_exit_code);
|
||||
assert_eq!(child_exit_code, 0);
|
||||
println!("pipetest passed!");
|
||||
0
|
||||
}
|
||||
}
|
21
user/src/bin/run_pipe_test.rs
Normal file
21
user/src/bin/run_pipe_test.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use user_lib::{fork, exec, wait};
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() -> i32 {
|
||||
for i in 0..1000 {
|
||||
if fork() == 0 {
|
||||
exec("pipe_large_test\0");
|
||||
} else {
|
||||
let mut _unused: i32 = 0;
|
||||
wait(&mut _unused);
|
||||
println!("Iter {} OK.", i);
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
use super::exit;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
|
||||
let err = panic_info.message().unwrap();
|
||||
|
@ -6,5 +8,5 @@ fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
|
|||
} else {
|
||||
println!("Panicked: {}", err);
|
||||
}
|
||||
loop {}
|
||||
exit(-1);
|
||||
}
|
|
@ -9,6 +9,8 @@ pub mod console;
|
|||
mod syscall;
|
||||
mod lang_items;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use syscall::*;
|
||||
use buddy_system_allocator::LockedHeap;
|
||||
|
||||
|
@ -40,6 +42,8 @@ fn main() -> i32 {
|
|||
panic!("Cannot find main!");
|
||||
}
|
||||
|
||||
pub fn close(fd: usize) -> isize { sys_close(fd) }
|
||||
pub fn pipe(pipe_fd: &mut [usize]) -> isize { sys_pipe(pipe_fd) }
|
||||
pub fn read(fd: usize, buf: &mut [u8]) -> isize { sys_read(fd, buf) }
|
||||
pub fn write(fd: usize, buf: &[u8]) -> isize { sys_write(fd, buf) }
|
||||
pub fn exit(exit_code: i32) -> ! { sys_exit(exit_code); }
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const SYSCALL_CLOSE: usize = 57;
|
||||
const SYSCALL_PIPE: usize = 59;
|
||||
const SYSCALL_READ: usize = 63;
|
||||
const SYSCALL_WRITE: usize = 64;
|
||||
const SYSCALL_EXIT: usize = 93;
|
||||
|
@ -21,6 +23,14 @@ fn syscall(id: usize, args: [usize; 3]) -> isize {
|
|||
ret
|
||||
}
|
||||
|
||||
pub fn sys_close(fd: usize) -> isize {
|
||||
syscall(SYSCALL_CLOSE, [fd, 0, 0])
|
||||
}
|
||||
|
||||
pub fn sys_pipe(pipe: &mut [usize]) -> isize {
|
||||
syscall(SYSCALL_PIPE, [pipe.as_mut_ptr() as usize, 0, 0])
|
||||
}
|
||||
|
||||
pub fn sys_read(fd: usize, buffer: &mut [u8]) -> isize {
|
||||
syscall(SYSCALL_READ, [fd, buffer.as_mut_ptr() as usize, buffer.len()])
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue