Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add HermitOS support for vectored read/write operations #126135

Merged
merged 1 commit into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,12 @@ name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"

[[package]]
name = "hermit-abi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",
Expand Down Expand Up @@ -2636,7 +2642,7 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"hermit-abi 0.3.9",
"libc",
]

Expand Down Expand Up @@ -5363,7 +5369,7 @@ dependencies = [
"dlmalloc",
"fortanix-sgx-abi",
"hashbrown",
"hermit-abi",
"hermit-abi 0.4.0",
"libc",
"miniz_oxide",
"object 0.36.0",
Expand Down
2 changes: 1 addition & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] }
fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'], public = true }

[target.'cfg(target_os = "hermit")'.dependencies]
hermit-abi = { version = "0.3.9", features = ['rustc-dep-of-std'], public = true }
hermit-abi = { version = "0.4.0", features = ['rustc-dep-of-std'], public = true }

[target.'cfg(target_os = "wasi")'.dependencies]
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
Expand Down
39 changes: 38 additions & 1 deletion library/std/src/sys/pal/hermit/fd.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#![unstable(reason = "not public", issue = "none", feature = "fd")]

use super::hermit_abi;
use crate::io::{self, Read};
use crate::cmp;
use crate::io::{self, IoSlice, IoSliceMut, Read};
use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
use crate::sys::cvt;
use crate::sys::unsupported;
use crate::sys_common::{AsInner, FromInner, IntoInner};

use crate::os::hermit::io::*;

const fn max_iov() -> usize {
hermit_abi::IOV_MAX
}

#[derive(Debug)]
pub struct FileDesc {
fd: OwnedFd,
Expand All @@ -21,6 +26,22 @@ impl FileDesc {
Ok(result as usize)
}

pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let ret = cvt(unsafe {
hermit_abi::readv(
self.as_raw_fd(),
bufs.as_mut_ptr() as *mut hermit_abi::iovec as *const hermit_abi::iovec,
cmp::min(bufs.len(), max_iov()),
)
})?;
Ok(ret as usize)
}

#[inline]
pub fn is_read_vectored(&self) -> bool {
true
}

pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
let mut me = self;
(&mut me).read_to_end(buf)
Expand All @@ -32,6 +53,22 @@ impl FileDesc {
Ok(result as usize)
}

pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let ret = cvt(unsafe {
hermit_abi::writev(
self.as_raw_fd(),
bufs.as_ptr() as *const hermit_abi::iovec,
cmp::min(bufs.len(), max_iov()),
)
})?;
Ok(ret as usize)
}

#[inline]
pub fn is_write_vectored(&self) -> bool {
true
}

pub fn duplicate(&self) -> io::Result<FileDesc> {
self.duplicate_path(&[])
}
Expand Down
45 changes: 19 additions & 26 deletions library/std/src/sys/pal/hermit/fs.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::fd::FileDesc;
use super::hermit_abi::{
self, dirent64, stat as stat_struct, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT,
O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
};
use crate::ffi::{CStr, OsStr, OsString};
use crate::fmt;
Expand Down Expand Up @@ -62,7 +62,7 @@ pub struct DirEntry {
/// 64-bit inode number
ino: u64,
/// File type
type_: u32,
type_: u8,
/// name of the entry
name: OsString,
}
Expand Down Expand Up @@ -90,7 +90,7 @@ pub struct FilePermissions {

#[derive(Copy, Clone, Eq, Debug)]
pub struct FileType {
mode: u32,
mode: u8,
}

impl PartialEq for FileType {
Expand All @@ -112,31 +112,23 @@ pub struct DirBuilder {

impl FileAttr {
pub fn modified(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(
self.stat_val.st_mtime.try_into().unwrap(),
self.stat_val.st_mtime_nsec.try_into().unwrap(),
))
Ok(SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec))
}

pub fn accessed(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(
self.stat_val.st_atime.try_into().unwrap(),
self.stat_val.st_atime_nsec.try_into().unwrap(),
))
Ok(SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec))
}

pub fn created(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(
self.stat_val.st_ctime.try_into().unwrap(),
self.stat_val.st_ctime_nsec.try_into().unwrap(),
))
Ok(SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec))
}

pub fn size(&self) -> u64 {
self.stat_val.st_size as u64
}

pub fn perm(&self) -> FilePermissions {
FilePermissions { mode: (self.stat_val.st_mode) }
FilePermissions { mode: self.stat_val.st_mode }
}

pub fn file_type(&self) -> FileType {
Expand Down Expand Up @@ -220,7 +212,7 @@ impl Iterator for ReadDir {
let entry = DirEntry {
root: self.inner.root.clone(),
ino: dir.d_ino,
type_: dir.d_type as u32,
type_: dir.d_type,
name: OsString::from_vec(name_bytes.to_vec()),
};

Expand Down Expand Up @@ -251,7 +243,7 @@ impl DirEntry {
}

pub fn file_type(&self) -> io::Result<FileType> {
Ok(FileType { mode: self.type_ as u32 })
Ok(FileType { mode: self.type_ })
}

#[allow(dead_code)]
Expand Down Expand Up @@ -385,12 +377,12 @@ impl File {
}

pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
self.0.read_vectored(bufs)
}

#[inline]
pub fn is_read_vectored(&self) -> bool {
false
self.0.is_read_vectored()
}

pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
Expand All @@ -402,12 +394,12 @@ impl File {
}

pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
self.0.write_vectored(bufs)
}

#[inline]
pub fn is_write_vectored(&self) -> bool {
false
self.0.is_write_vectored()
}

#[inline]
Expand Down Expand Up @@ -439,13 +431,13 @@ impl DirBuilder {

pub fn mkdir(&self, path: &Path) -> io::Result<()> {
run_path_with_cstr(path, &|path| {
cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode) }).map(|_| ())
cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode.into()) }).map(|_| ())
})
}

#[allow(dead_code)]
pub fn set_mode(&mut self, mode: u32) {
self.mode = mode as u32;
self.mode = mode;
}
}

Expand Down Expand Up @@ -501,8 +493,9 @@ impl FromRawFd for File {
}

pub fn readdir(path: &Path) -> io::Result<ReadDir> {
let fd_raw =
run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::opendir(path.as_ptr()) }))?;
let fd_raw = run_path_with_cstr(path, &|path| {
cvt(unsafe { hermit_abi::open(path.as_ptr(), O_RDONLY | O_DIRECTORY, 0) })
})?;
let fd = unsafe { FileDesc::from_raw_fd(fd_raw as i32) };
let root = path.to_path_buf();

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/hermit/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
let timespec = timeout.and_then(|dur| {
Some(hermit_abi::timespec {
tv_sec: dur.as_secs().try_into().ok()?,
tv_nsec: dur.subsec_nanos().into(),
tv_nsec: dur.subsec_nanos().try_into().ok()?,
})
});

Expand Down
82 changes: 82 additions & 0 deletions library/std/src/sys/pal/hermit/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::marker::PhantomData;
use crate::os::hermit::io::{AsFd, AsRawFd};
use crate::slice;

use hermit_abi::{c_void, iovec};

#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct IoSlice<'a> {
vec: iovec,
_p: PhantomData<&'a [u8]>,
}

impl<'a> IoSlice<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
IoSlice {
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
_p: PhantomData,
}
}

#[inline]
pub fn advance(&mut self, n: usize) {
if self.vec.iov_len < n {
panic!("advancing IoSlice beyond its length");
}

unsafe {
self.vec.iov_len -= n;
self.vec.iov_base = self.vec.iov_base.add(n);
}
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}
}

#[repr(transparent)]
pub struct IoSliceMut<'a> {
vec: iovec,
_p: PhantomData<&'a mut [u8]>,
}

impl<'a> IoSliceMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
IoSliceMut {
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
_p: PhantomData,
}
}

#[inline]
pub fn advance(&mut self, n: usize) {
if self.vec.iov_len < n {
panic!("advancing IoSliceMut beyond its length");
}

unsafe {
self.vec.iov_len -= n;
self.vec.iov_base = self.vec.iov_base.add(n);
}
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}
}

pub fn is_terminal(fd: &impl AsFd) -> bool {
let fd = fd.as_fd();
hermit_abi::isatty(fd.as_raw_fd())
}
1 change: 0 additions & 1 deletion library/std/src/sys/pal/hermit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ pub mod env;
pub mod fd;
pub mod fs;
pub mod futex;
#[path = "../unsupported/io.rs"]
pub mod io;
pub mod net;
pub mod os;
Expand Down
13 changes: 6 additions & 7 deletions library/std/src/sys/pal/hermit/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ impl Socket {
}

pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
crate::io::default_read_vectored(|b| self.read(b), bufs)
self.0.read_vectored(bufs)
}

#[inline]
pub fn is_read_vectored(&self) -> bool {
false
self.0.is_read_vectored()
}

fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
Expand Down Expand Up @@ -209,16 +209,15 @@ impl Socket {
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let sz = cvt(unsafe { netc::write(self.0.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
Ok(sz.try_into().unwrap())
self.0.write(buf)
}

pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
crate::io::default_write_vectored(|b| self.write(b), bufs)
self.0.write_vectored(bufs)
}

pub fn is_write_vectored(&self) -> bool {
false
self.0.is_write_vectored()
}

pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> {
Expand Down Expand Up @@ -265,7 +264,7 @@ impl Socket {
Shutdown::Read => netc::SHUT_RD,
Shutdown::Both => netc::SHUT_RDWR,
};
cvt(unsafe { netc::shutdown_socket(self.as_raw_fd(), how) })?;
cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?;
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/hermit/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,5 @@ pub fn exit(code: i32) -> ! {
}

pub fn getpid() -> u32 {
unsafe { hermit_abi::getpid() }
unsafe { hermit_abi::getpid() as u32 }
}
Loading
Loading