From 3f1d46a626f79fa6b9892be0457cc76c3e25326b Mon Sep 17 00:00:00 2001 From: scPointer Date: Thu, 21 Mar 2024 22:29:30 +0800 Subject: [PATCH] complete zlm_1_4: pipe; checked zlm_1_3: futex private wake; add comment for zlm_1_5 --- .gitignore | 1 + modules/axmem/src/lib.rs | 2 + ulib/axstarry/src/syscall_fs/ctype/pipe.rs | 54 +++++++++++++++++----- ulib/axstarry/src/syscall_fs/imp/io.rs | 5 +- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 5fa61e2fc6..71157ad012 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ qemu.log rusty-tags.vi /testcases/riscv64-linux-musl-native.tgz /testcases/gcc/riscv64-linux-musl-native +/testcases/ZLM/MediaServer testsuits-x86_64-linux-musl.tgz .idea/ arceos-fada.bin.gz diff --git a/modules/axmem/src/lib.rs b/modules/axmem/src/lib.rs index cbced643be..277fe1310a 100644 --- a/modules/axmem/src/lib.rs +++ b/modules/axmem/src/lib.rs @@ -401,6 +401,8 @@ impl MemorySet { } None => { error!("Page fault address {:?} not found in memory set ", addr); + // 如果不加 panic,此处会无限循环触发 page fault + // 这是由于 ZLM 第一阶段任务五的 clone3 实现不完善导致的,修复后需删掉这个 panic panic!("FIXME: Page fault shouldn't cause a panic in kernel."); Err(AxError::BadAddress) } diff --git a/ulib/axstarry/src/syscall_fs/ctype/pipe.rs b/ulib/axstarry/src/syscall_fs/ctype/pipe.rs index 18f91818c9..e707206502 100644 --- a/ulib/axstarry/src/syscall_fs/ctype/pipe.rs +++ b/ulib/axstarry/src/syscall_fs/ctype/pipe.rs @@ -1,4 +1,4 @@ -use axfs::api::{FileIO, FileIOType}; +use axfs::api::{FileIO, FileIOType, OpenFlags}; extern crate alloc; use alloc::sync::{Arc, Weak}; use axerrno::AxResult; @@ -14,28 +14,33 @@ pub struct Pipe { #[allow(unused)] writable: bool, buffer: Arc>, - non_block: bool, + #[allow(unused)] + flags: Mutex, } impl Pipe { /// create readable pipe - pub fn read_end_with_buffer(buffer: Arc>, non_block: bool) -> Self { + pub fn read_end_with_buffer(buffer: Arc>, flags: OpenFlags) -> Self { Self { readable: true, writable: false, buffer, - non_block, + flags: Mutex::new(flags | OpenFlags::RDONLY), } } /// create writable pipe - pub fn write_end_with_buffer(buffer: Arc>, non_block: bool) -> Self { + pub fn write_end_with_buffer(buffer: Arc>, flags: OpenFlags) -> Self { Self { readable: false, writable: true, buffer, - non_block, + flags: Mutex::new(flags | OpenFlags::WRONLY), } } + /// is it set non block? + pub fn is_non_block(&self) -> bool { + self.flags.lock().contains(OpenFlags::NON_BLOCK) + } } const RING_BUFFER_SIZE: usize = 0x4000; @@ -109,11 +114,11 @@ impl PipeRingBuffer { } /// Return (read_end, write_end) -pub fn make_pipe(non_block: bool) -> (Arc, Arc) { +pub fn make_pipe(flags: OpenFlags) -> (Arc, Arc) { trace!("kernel: make_pipe"); let buffer = Arc::new(Mutex::new(PipeRingBuffer::new())); - let read_end = Arc::new(Pipe::read_end_with_buffer(buffer.clone(), non_block)); - let write_end = Arc::new(Pipe::write_end_with_buffer(buffer.clone(), non_block)); + let read_end = Arc::new(Pipe::read_end_with_buffer(buffer.clone(), flags)); + let write_end = Arc::new(Pipe::write_end_with_buffer(buffer.clone(), flags)); buffer.lock().set_write_end(&write_end); (read_end, write_end) } @@ -137,7 +142,7 @@ impl FileIO for Pipe { } if Arc::strong_count(&self.buffer) < 2 || ring_buffer.all_write_ends_closed() - || self.non_block + || self.is_non_block() { return Ok(already_read); } @@ -173,7 +178,7 @@ impl FileIO for Pipe { if loop_write == 0 { drop(ring_buffer); - if Arc::strong_count(&self.buffer) < 2 || self.non_block { + if Arc::strong_count(&self.buffer) < 2 || self.is_non_block() { // 读入端关闭 return Ok(already_write); } @@ -235,4 +240,31 @@ impl FileIO for Pipe { fn ready_to_write(&self) -> bool { self.writable && self.buffer.lock().available_write() != 0 } + + /// 设置文件状态 + fn set_status(&self, flags: OpenFlags) -> bool { + if flags.contains(OpenFlags::CLOEXEC) { + *self.flags.lock() = flags; + true + } else { + false + } + } + + /// 获取文件状态 + fn get_status(&self) -> OpenFlags { + *self.flags.lock() + } + + /// 设置 close_on_exec 位 + /// 设置成功返回false + fn set_close_on_exec(&self, is_set: bool) -> bool { + if is_set { + // 设置close_on_exec位置 + *self.flags.lock() |= OpenFlags::CLOEXEC; + } else { + *self.flags.lock() &= !OpenFlags::CLOEXEC; + } + true + } } diff --git a/ulib/axstarry/src/syscall_fs/imp/io.rs b/ulib/axstarry/src/syscall_fs/imp/io.rs index 5f254c4656..7ee9bdc119 100644 --- a/ulib/axstarry/src/syscall_fs/imp/io.rs +++ b/ulib/axstarry/src/syscall_fs/imp/io.rs @@ -220,14 +220,13 @@ pub fn syscall_writev(args: [usize; 6]) -> SyscallResult { /// 注意:`fd[2]`是32位数组,所以这里的 fd 是 u32 类型的指针,而不是 usize 类型的指针。 pub fn syscall_pipe2(args: [usize; 6]) -> SyscallResult { let fd = args[0] as *mut u32; - let flags = args[1]; + let flags = args[1] as u32; axlog::info!("Into syscall_pipe2. fd: {} flags: {}", fd as usize, flags); let process = current_process(); if process.manual_alloc_for_lazy((fd as usize).into()).is_err() { return Err(SyscallError::EINVAL); } - let non_block = (flags & 0x800) != 0; - let (read, write) = make_pipe(non_block); + let (read, write) = make_pipe(OpenFlags::from_bits_truncate(flags)); let mut fd_table = process.fd_manager.fd_table.lock(); let fd_num = if let Ok(fd) = process.alloc_fd(&mut fd_table) { fd