diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..e703cfb7 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,6 @@ +[profile.release] +#strip = true +#incremental = true +#debug = true +opt-level = 3 +lto = true diff --git a/Cargo.lock b/Cargo.lock index d8bcb5c2..9041b746 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1129,9 +1129,6 @@ dependencies = [ [[package]] name = "ftest" version = "0.1.0" -dependencies = [ - "Mstd", -] [[package]] name = "gethostname" diff --git a/Cargo.toml b/Cargo.toml index 57bdeab8..05e5f87d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,6 @@ members = [ "user/apps/*", "user/musl/hello", "user/musl/async_test", + "user/musl/ftest", ] - -[profile.release] -#lto = true -#codegen-units = 1 - diff --git a/kernel/src/net/mod.rs b/kernel/src/net/mod.rs index 0a0dba4e..a53d8ac1 100644 --- a/kernel/src/net/mod.rs +++ b/kernel/src/net/mod.rs @@ -10,7 +10,7 @@ use alloc::{sync::Arc, vec, vec::Vec}; use constants::{io::OpenFlags, net::*, AlienResult, LinuxErrno}; use knet::{ addr::RawIpV4Addr, - socket::{SocketData, SocketFile, SocketFileExt}, + socket::{Socket, SocketData, SocketFile, SocketFileExt}, }; use vfs::kfile::File; @@ -460,21 +460,45 @@ pub fn socket_pair(domain: usize, s_type: usize, protocol: usize, sv: usize) -> } // println_color!(32, // "socketpair: {:?}, {:?}, {:?}, {:?}", - // domain, s_type, protocol, sv + // domain, socket_type, protocol, sv // ); let file1 = SocketData::new(domain, socket_type, protocol)?; - let file2 = file1.clone(); - info!("socket domain: {:?}, type: {:?}", domain, socket_type); + let file2 = SocketData::new(domain, socket_type, protocol)?; if s_type & SocketType::SOCK_NONBLOCK as usize != 0 { let socket = file1.get_socketdata()?; file1.set_open_flag(file1.get_open_flag() | OpenFlags::O_NONBLOCK); socket.set_socket_nonblock(true); + let socket = file2.get_socketdata()?; + file2.set_open_flag(file2.get_open_flag() | OpenFlags::O_NONBLOCK); + socket.set_socket_nonblock(true); info!("socket with nonblock"); } if s_type & SocketType::SOCK_CLOEXEC as usize != 0 { file1.set_close_on_exec(); + file2.set_close_on_exec(); info!("socket with cloexec"); } + + let socket_guard = file1.get_socketdata()?; + match &socket_guard.socket { + Socket::Unix(unix_socket) => { + unix_socket.set_remote(&(file2)); + } + _ => { + panic!("socket_pair: unsupported socket type") + } + } + drop(socket_guard); + let socket_guard = file2.get_socketdata()?; + match &socket_guard.socket { + Socket::Unix(unix_socket) => { + unix_socket.set_remote(&file1); + } + _ => { + panic!("socket_pair: unsupported socket type") + } + } + drop(socket_guard); let task = current_task().unwrap(); let fd1 = task.add_file(file1).map_err(|_| LinuxErrno::EMFILE)?; let fd2 = task.add_file(file2).map_err(|_| LinuxErrno::EMFILE)?; diff --git a/kernel/src/task/cpu.rs b/kernel/src/task/cpu.rs index 313a1b97..6053248f 100644 --- a/kernel/src/task/cpu.rs +++ b/kernel/src/task/cpu.rs @@ -166,7 +166,7 @@ pub fn do_exit(exit_code: i32, exit_group: u8) -> isize { /// 目前该系统调用直接调用[`do_exit`],有关进程组的相关功能有待实现。 #[syscall_func(94)] pub fn exit_group(exit_code: i32) -> isize { - do_exit(exit_code, 1) + do_exit(exit_code, 0) } pub fn check_exit_group() { diff --git a/kernel/src/time.rs b/kernel/src/time.rs index e18b2da5..0bddc3df 100644 --- a/kernel/src/time.rs +++ b/kernel/src/time.rs @@ -21,11 +21,30 @@ use constants::{ use log::{info, warn}; use platform::{config::CLOCK_FREQ, set_timer}; use syscall_table::syscall_func; -use timer::{read_timer, TimeNow, Times, ToClock}; +use timer::{get_time_ms, read_timer, TimeNow, Times, ToClock}; use vfs::timerfd::TimerFile; use crate::task::{current_task, do_suspend, StatisticalData}; +#[inline] +#[allow(unused)] +pub fn read_time_ms() -> u64 { + get_time_ms() as u64 +} + +#[inline] +#[allow(unused)] +pub fn read_time_ns() -> u64 { + let time = read_timer(); + time as u64 * 1_000_000_000 / CLOCK_FREQ as u64 +} + +#[inline] +#[allow(unused)] +pub fn read_time_us() -> u64 { + let time = read_timer(); + time as u64 * 1_000_000 / CLOCK_FREQ as u64 +} /// 每秒包含的 时间片 数,每隔一个时间片,就会产生一个时钟中断 const TICKS_PER_SEC: usize = 10; // const TICKS_PER_SEC_IN_KERNEL: usize = 1000; diff --git a/subsystems/knet/src/socket.rs b/subsystems/knet/src/socket.rs index b641272a..067e46cc 100644 --- a/subsystems/knet/src/socket.rs +++ b/subsystems/knet/src/socket.rs @@ -10,7 +10,7 @@ use alloc::{boxed::Box, sync::Arc}; use core::{ fmt::{Debug, Formatter}, - net::SocketAddr, + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, }; use constants::{ @@ -266,7 +266,7 @@ impl SocketData { .map_err(neterror2alien)?; } _ => { - panic!("bind is not supported") + panic!("bind is not supported socket addr: {:?}", socket_addr); } } Ok(()) @@ -329,8 +329,9 @@ impl SocketData { udp.send(message).map_err(neterror2alien) } } + Socket::Unix(unix) => unix.send_to(message), _ => { - panic!("bind is not supported") + panic!("send_to is not supported") } } } @@ -348,6 +349,11 @@ impl SocketData { // let peer_addr = udp.peer_addr().map_err(neterror2linux)?; Ok((recv.0, recv.1)) } + Socket::Unix(unix) => { + let socket_addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)); + let len = unix.recvfrom(message)?; + Ok((len, socket_addr)) + } _ => { panic!("bind is not supported") } @@ -434,8 +440,9 @@ impl SocketData { false } } + Socket::Unix(unix) => unix.ready_read(), _ => { - panic!("bind is not supported") + panic!("ready_read is not supported") } } } diff --git a/subsystems/knet/src/unix.rs b/subsystems/knet/src/unix.rs index ba866cf5..33722978 100644 --- a/subsystems/knet/src/unix.rs +++ b/subsystems/knet/src/unix.rs @@ -1,30 +1,74 @@ //! 有关 Unix 协议族下的套接字结构。(目前有关的功能有待支持) -use alloc::{string::String, sync::Arc}; +use alloc::{ + string::String, + sync::{Arc, Weak}, + vec::Vec, +}; -use constants::LinuxErrno; +use constants::{AlienResult, LinuxErrno}; use ksync::Mutex; -use vfs::kfile::File; + +use crate::socket::{Socket, SocketFile, SocketFileExt}; /// Unix 协议族下的套接字结构 #[allow(unused)] pub struct UnixSocket { - /// 文件路径,即套接字地址 - file_path: Mutex>, - /// 套接字数据 - file: Mutex>>, + inner: Mutex, +} + +struct UnixSocketInner { + remote: Weak, + buf: Vec, } impl UnixSocket { /// 创建一个新的 Unix 协议族下的套接字结构 pub fn new() -> Self { Self { - file_path: Mutex::new(None), - file: Mutex::new(None), + inner: Mutex::new(UnixSocketInner { + remote: Weak::::new(), + buf: Vec::new(), + }), } } /// UnixSocket 的 connect 操作 - pub fn connect(&self, _file_path: String) -> Result<(), LinuxErrno> { + pub fn connect(&self, _file_path: String) -> AlienResult<()> { Err(LinuxErrno::ENOENT) } + + pub fn set_remote(&self, remote: &Arc) { + self.inner.lock().remote = Arc::downgrade(remote); + } + + pub fn send_to(&self, buf: &[u8]) -> AlienResult { + if let Some(remote) = self.inner.lock().remote.upgrade() { + let socket_guard = remote.get_socketdata()?; + match socket_guard.socket { + Socket::Unix(ref unix_socket) => { + unix_socket.inner.lock().buf.extend_from_slice(buf); + Ok(buf.len()) + } + _ => Err(LinuxErrno::EINVAL), + } + } else { + Err(LinuxErrno::ENOTCONN) + } + } + + pub fn ready_read(&self) -> bool { + self.inner.lock().buf.len() > 0 + } + + pub fn recvfrom(&self, buf: &mut [u8]) -> AlienResult { + let inner_buf = &mut self.inner.lock().buf; + if inner_buf.len() > 0 { + let len = inner_buf.len().min(buf.len()); + buf[..len].copy_from_slice(&inner_buf[..len]); + inner_buf.drain(..len); + Ok(len) + } else { + Err(LinuxErrno::EAGAIN) + } + } } diff --git a/subsystems/platform/src/hifive_riscv/config.rs b/subsystems/platform/src/hifive_riscv/config.rs index 5b99f7a2..32358366 100644 --- a/subsystems/platform/src/hifive_riscv/config.rs +++ b/subsystems/platform/src/hifive_riscv/config.rs @@ -1,6 +1,6 @@ pub const CLOCK_FREQ: usize = 100_0000; pub const BLOCK_CACHE_FRAMES: usize = 1024 * 4 * 4; -pub const HEAP_SIZE: usize = 0x40_00000; //64M +pub const HEAP_SIZE: usize = 0x70_00000; //64M pub const MMIO: &[(usize, usize)] = &[ (0xc000000, 0x4000000), //PLIC diff --git a/subsystems/platform/src/qemu_riscv/config.rs b/subsystems/platform/src/qemu_riscv/config.rs index 6b1ae780..c01778bc 100644 --- a/subsystems/platform/src/qemu_riscv/config.rs +++ b/subsystems/platform/src/qemu_riscv/config.rs @@ -1,6 +1,6 @@ pub const CLOCK_FREQ: usize = 1250_0000; pub const BLOCK_CACHE_FRAMES: usize = 1024 * 4 * 4; -pub const HEAP_SIZE: usize = 0x40_00000; // (32+6)MB +pub const HEAP_SIZE: usize = 0x70_00000; // (32+6)MB /// qemu的设备地址空间 pub const MMIO: &[(usize, usize)] = &[ diff --git a/subsystems/platform/src/starfive2_riscv/config.rs b/subsystems/platform/src/starfive2_riscv/config.rs index c00cb352..21e87c49 100644 --- a/subsystems/platform/src/starfive2_riscv/config.rs +++ b/subsystems/platform/src/starfive2_riscv/config.rs @@ -1,6 +1,6 @@ pub const CLOCK_FREQ: usize = 400_0000; pub const BLOCK_CACHE_FRAMES: usize = 1024 * 4 * 4; -pub const HEAP_SIZE: usize = 0x40_00000; +pub const HEAP_SIZE: usize = 0x70_00000; /// vf2的设备地址空间 diff --git a/tests/testbin-second-stage/bash2 b/tests/testbin-second-stage/bash2 new file mode 100644 index 00000000..ef3d71cb Binary files /dev/null and b/tests/testbin-second-stage/bash2 differ diff --git a/tools/qemu-loongarch-runenv b/tools/qemu-loongarch-runenv deleted file mode 160000 index bb489fe1..00000000 --- a/tools/qemu-loongarch-runenv +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bb489fe14a6a3ad72cccd952bffea4d82a0e14ee diff --git a/user/apps/Makefile b/user/apps/Makefile index bb2899b6..1d1da497 100644 --- a/user/apps/Makefile +++ b/user/apps/Makefile @@ -26,7 +26,6 @@ BUILD_CRATES := \ sleep \ socket_test \ final_test \ - ftest \ # shell \ print \ diff --git a/user/apps/ftest/src/main.rs b/user/apps/ftest/src/main.rs deleted file mode 100644 index ef972977..00000000 --- a/user/apps/ftest/src/main.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![no_std] -#![no_main] -use Mstd::{ - fs::{close, open, read, OpenFlags}, - println, - time::get_time_ms, -}; - -#[no_mangle] -fn main() -> isize { - read_bash_test(); - // in cache - read_bash_test(); - 0 -} - -fn read_bash_test() -> isize { - let bash_file_test = open("/tests/bash\0", OpenFlags::O_RDONLY); - if bash_file_test < 0 { - println!("Failed to open /tests/bash"); - return -1; - } - let now = get_time_ms(); - let mut buf = [0u8; 100]; - let mut bytes = 0; - loop { - let res = read(bash_file_test as usize, &mut buf); - if res == 0 { - break; - } - bytes += res; - } - let new = get_time_ms(); - let time = new - now; - let speed = bytes as f64 / time as f64 * 1000.0 / 1024.0; - println!( - "Read {} bytes in {}ms, speed: {} KB/s", - bytes, time, speed as isize - ); - close(bash_file_test as _); - 0 -} diff --git a/user/musl/Makefile b/user/musl/Makefile index 787b7a1c..3bbd2451 100644 --- a/user/musl/Makefile +++ b/user/musl/Makefile @@ -18,4 +18,5 @@ build: BUILD_CRATES := \ hello \ - async_test \ No newline at end of file + async_test \ + ftest \ No newline at end of file diff --git a/user/apps/ftest/Cargo.toml b/user/musl/ftest/Cargo.toml similarity index 56% rename from user/apps/ftest/Cargo.toml rename to user/musl/ftest/Cargo.toml index 1340e183..380fdd4c 100644 --- a/user/apps/ftest/Cargo.toml +++ b/user/musl/ftest/Cargo.toml @@ -3,5 +3,4 @@ name = "ftest" version = "0.1.0" edition = "2021" -[dependencies] -Mstd = {path = "../../userlib" } \ No newline at end of file +[dependencies] \ No newline at end of file diff --git a/user/musl/ftest/src/main.rs b/user/musl/ftest/src/main.rs new file mode 100644 index 00000000..70144b85 --- /dev/null +++ b/user/musl/ftest/src/main.rs @@ -0,0 +1,36 @@ +use std::{fs::File, io::Read, time::Instant}; + +fn main() { + read_bash_test(); + // in cache + read_bash_test(); + // read_once_test(); +} +fn read_bash_test() { + let mut file = File::open("/tests/bash2").unwrap(); + let now = Instant::now(); + let mut buf = [0u8; 4096]; + let mut bytes = 0; + loop { + let res = file.read(&mut buf).unwrap(); + if res == 0 { + break; + } + bytes += res; + } + let ms = now.elapsed().as_millis(); + let speed = bytes as f64 * 1000.0 / ms as f64 / 1024.0; + println!( + "Read {} bytes in {}ms, speed: {} KB/s", + bytes, ms, speed as isize + ); +} + +fn read_once_test() { + let mut file = File::open("/tests/bash2").unwrap(); + let now = Instant::now(); + let mut buf = [0u8; 4096]; + let res = file.read(&mut buf).unwrap(); + let ms = now.elapsed().as_micros(); + println!("Read {} bytes in {}us", res, ms); +}