From 5389b7adca66ff3d5127b7438115859e4eaa78ae Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Tue, 18 Jan 2022 03:33:58 -0800 Subject: [PATCH] Remove pipe && Fix cat and huge_write. --- os/src/fs/mod.rs | 4 +- os/src/fs/pipe.rs | 168 -------------------------------- os/src/syscall/fs.rs | 32 +----- os/src/syscall/mod.rs | 4 - user/src/bin/cat.rs | 8 +- user/src/bin/huge_write.rs | 4 +- user/src/bin/pipe_large_test.rs | 69 ------------- user/src/bin/pipetest.rs | 44 --------- user/src/lib.rs | 1 - user/src/syscall.rs | 5 - 10 files changed, 7 insertions(+), 332 deletions(-) delete mode 100644 os/src/fs/pipe.rs delete mode 100644 user/src/bin/pipe_large_test.rs delete mode 100644 user/src/bin/pipetest.rs diff --git a/os/src/fs/mod.rs b/os/src/fs/mod.rs index c015702d..ecc0d155 100644 --- a/os/src/fs/mod.rs +++ b/os/src/fs/mod.rs @@ -1,4 +1,3 @@ -mod pipe; mod stdio; mod inode; @@ -11,6 +10,5 @@ pub trait File : Send + Sync { fn write(&self, buf: UserBuffer) -> usize; } -pub use pipe::{Pipe, make_pipe}; pub use stdio::{Stdin, Stdout}; -pub use inode::{OSInode, open_file, OpenFlags, list_apps}; \ No newline at end of file +pub use inode::{OSInode, open_file, OpenFlags, list_apps}; diff --git a/os/src/fs/pipe.rs b/os/src/fs/pipe.rs deleted file mode 100644 index ed2dde15..00000000 --- a/os/src/fs/pipe.rs +++ /dev/null @@ -1,168 +0,0 @@ -use super::File; -use alloc::sync::{Arc, Weak}; -use crate::sync::UPSafeCell; -use crate::mm::UserBuffer; - -use crate::task::suspend_current_and_run_next; - -pub struct Pipe { - readable: bool, - writable: bool, - buffer: Arc>, -} - -impl Pipe { - pub fn read_end_with_buffer(buffer: Arc>) -> Self { - Self { - readable: true, - writable: false, - buffer, - } - } - pub fn write_end_with_buffer(buffer: Arc>) -> Self { - Self { - readable: false, - writable: true, - buffer, - } - } -} - -const RING_BUFFER_SIZE: usize = 32; - -#[derive(Copy, Clone, PartialEq)] -enum RingBufferStatus { - FULL, - EMPTY, - NORMAL, -} - -pub struct PipeRingBuffer { - arr: [u8; RING_BUFFER_SIZE], - head: usize, - tail: usize, - status: RingBufferStatus, - write_end: Option>, -} - -impl PipeRingBuffer { - pub fn new() -> Self { - Self { - arr: [0; RING_BUFFER_SIZE], - head: 0, - tail: 0, - status: RingBufferStatus::EMPTY, - write_end: None, - } - } - pub fn set_write_end(&mut self, write_end: &Arc) { - self.write_end = Some(Arc::downgrade(write_end)); - } - pub fn write_byte(&mut self, byte: u8) { - self.status = RingBufferStatus::NORMAL; - self.arr[self.tail] = byte; - self.tail = (self.tail + 1) % RING_BUFFER_SIZE; - if self.tail == self.head { - self.status = RingBufferStatus::FULL; - } - } - pub fn read_byte(&mut self) -> u8 { - self.status = RingBufferStatus::NORMAL; - let c = self.arr[self.head]; - self.head = (self.head + 1) % RING_BUFFER_SIZE; - if self.head == self.tail { - self.status = RingBufferStatus::EMPTY; - } - c - } - pub fn available_read(&self) -> usize { - if self.status == RingBufferStatus::EMPTY { - 0 - } else { - if self.tail > self.head { - self.tail - self.head - } else { - self.tail + RING_BUFFER_SIZE - self.head - } - } - } - pub fn available_write(&self) -> usize { - if self.status == RingBufferStatus::FULL { - 0 - } else { - RING_BUFFER_SIZE - self.available_read() - } - } - pub fn all_write_ends_closed(&self) -> bool { - self.write_end.as_ref().unwrap().upgrade().is_none() - } -} - -/// Return (read_end, write_end) -pub fn make_pipe() -> (Arc, Arc) { - let buffer = Arc::new(unsafe { - UPSafeCell::new(PipeRingBuffer::new()) - }); - let read_end = Arc::new( - Pipe::read_end_with_buffer(buffer.clone()) - ); - let write_end = Arc::new( - Pipe::write_end_with_buffer(buffer.clone()) - ); - buffer.exclusive_access().set_write_end(&write_end); - (read_end, write_end) -} - -impl File for Pipe { - fn readable(&self) -> bool { self.readable } - fn writable(&self) -> bool { self.writable } - fn read(&self, buf: UserBuffer) -> usize { - assert_eq!(self.readable(), true); - let mut buf_iter = buf.into_iter(); - let mut read_size = 0usize; - loop { - let mut ring_buffer = self.buffer.exclusive_access(); - let loop_read = ring_buffer.available_read(); - if loop_read == 0 { - if ring_buffer.all_write_ends_closed() { - return read_size; - } - drop(ring_buffer); - suspend_current_and_run_next(); - continue; - } - // read at most loop_read bytes - for _ in 0..loop_read { - if let Some(byte_ref) = buf_iter.next() { - unsafe { *byte_ref = ring_buffer.read_byte(); } - read_size += 1; - } else { - return read_size; - } - } - } - } - fn write(&self, buf: UserBuffer) -> usize { - assert_eq!(self.writable(), true); - let mut buf_iter = buf.into_iter(); - let mut write_size = 0usize; - loop { - let mut ring_buffer = self.buffer.exclusive_access(); - let loop_write = ring_buffer.available_write(); - if loop_write == 0 { - drop(ring_buffer); - suspend_current_and_run_next(); - continue; - } - // write at most loop_write bytes - for _ in 0..loop_write { - if let Some(byte_ref) = buf_iter.next() { - ring_buffer.write_byte(unsafe { *byte_ref }); - write_size += 1; - } else { - return write_size; - } - } - } - } -} \ No newline at end of file diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs index 9e7c1857..d1063e76 100644 --- a/os/src/syscall/fs.rs +++ b/os/src/syscall/fs.rs @@ -1,12 +1,10 @@ use crate::mm::{ UserBuffer, translated_byte_buffer, - translated_refmut, translated_str, }; use crate::task::{current_user_token, current_task}; -use crate::fs::{make_pipe, OpenFlags, open_file}; -use alloc::sync::Arc; +use crate::fs::{OpenFlags, open_file}; pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize { let token = current_user_token(); @@ -81,31 +79,3 @@ pub fn sys_close(fd: usize) -> isize { inner.fd_table[fd].take(); 0 } - -pub fn sys_pipe(pipe: *mut usize) -> isize { - let task = current_task().unwrap(); - let token = current_user_token(); - let mut inner = task.inner_exclusive_access(); - let (pipe_read, pipe_write) = make_pipe(); - let read_fd = inner.alloc_fd(); - inner.fd_table[read_fd] = Some(pipe_read); - let write_fd = inner.alloc_fd(); - inner.fd_table[write_fd] = Some(pipe_write); - *translated_refmut(token, pipe) = read_fd; - *translated_refmut(token, unsafe { pipe.add(1) }) = write_fd; - 0 -} - -pub fn sys_dup(fd: usize) -> isize { - let task = current_task().unwrap(); - let mut inner = task.inner_exclusive_access(); - if fd >= inner.fd_table.len() { - return -1; - } - if inner.fd_table[fd].is_none() { - return -1; - } - let new_fd = inner.alloc_fd(); - inner.fd_table[new_fd] = Some(Arc::clone(inner.fd_table[fd].as_ref().unwrap())); - new_fd as isize -} \ No newline at end of file diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 4683d055..cd65aa78 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -1,7 +1,5 @@ -const SYSCALL_DUP: usize = 24; const SYSCALL_OPEN: usize = 56; 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; @@ -20,10 +18,8 @@ use process::*; pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { match syscall_id { - SYSCALL_DUP=> sys_dup(args[0]), SYSCALL_OPEN => sys_open(args[0] as *const u8, args[1] as u32), SYSCALL_CLOSE => sys_close(args[0]), - SYSCALL_PIPE => sys_pipe(args[0] as *mut usize), SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]), SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), diff --git a/user/src/bin/cat.rs b/user/src/bin/cat.rs index 988164d3..a5c9ee5c 100644 --- a/user/src/bin/cat.rs +++ b/user/src/bin/cat.rs @@ -21,14 +21,12 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 { panic!("Error occured when opening file"); } let fd = fd as usize; - let mut buf = [0u8; 16]; - let mut s = String::new(); + let mut buf = [0u8; 256]; loop { let size = read(fd, &mut buf) as usize; if size == 0 { break; } - s.push_str(core::str::from_utf8(&buf[..size]).unwrap()); + println!("{}", core::str::from_utf8(&buf[..size]).unwrap()); } - println!("{}", s); close(fd); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/huge_write.rs b/user/src/bin/huge_write.rs index f9dafa17..b00ca17b 100644 --- a/user/src/bin/huge_write.rs +++ b/user/src/bin/huge_write.rs @@ -18,7 +18,7 @@ pub fn main() -> i32 { for i in 0..buffer.len() { buffer[i] = i as u8; } - let f = open("testf", OpenFlags::CREATE | OpenFlags::WRONLY); + let f = open("testf\0", OpenFlags::CREATE | OpenFlags::WRONLY); if f < 0 { panic!("Open test file failed!"); } @@ -33,4 +33,4 @@ pub fn main() -> i32 { let speed_kbs = size_mb * 1000000 / time_ms; println!("{}MiB written, time cost = {}ms, write speed = {}KiB/s", size_mb, time_ms, speed_kbs); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/pipe_large_test.rs b/user/src/bin/pipe_large_test.rs deleted file mode 100644 index 121987be..00000000 --- a/user/src/bin/pipe_large_test.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![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::(); - 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::(); - 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::( - core::str::from_utf8(&child_result[..result_len]).unwrap() - ).unwrap() - ); - let mut _unused: i32 = 0; - wait(&mut _unused); - println!("pipe_large_test passed!"); - 0 - } -} \ No newline at end of file diff --git a/user/src/bin/pipetest.rs b/user/src/bin/pipetest.rs deleted file mode 100644 index c151fbdd..00000000 --- a/user/src/bin/pipetest.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![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; - // close read_end - close(pipe_fd[0]); - 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 - } -} \ No newline at end of file diff --git a/user/src/lib.rs b/user/src/lib.rs index daaaf8df..95d611db 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -71,7 +71,6 @@ bitflags! { pub fn dup(fd: usize) -> isize { sys_dup(fd) } pub fn open(path: &str, flags: OpenFlags) -> isize { sys_open(path, flags.bits) } 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); } diff --git a/user/src/syscall.rs b/user/src/syscall.rs index 9c30020c..4c1bffce 100644 --- a/user/src/syscall.rs +++ b/user/src/syscall.rs @@ -3,7 +3,6 @@ use core::arch::asm; const SYSCALL_DUP: usize = 24; const SYSCALL_OPEN: usize = 56; 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; @@ -40,10 +39,6 @@ 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()]) }