mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-29 21:41:47 +00:00
add HermitOS support of vectored read/write operations
In general, the I/O interface of hermit-abi is more POSIX-like interface. Consequently, platform abstraction layer for HermitOS has slightly adjusted and some inaccuracies remove.
This commit is contained in:
parent
e3c3ce62d7
commit
1f125a6716
10
Cargo.lock
10
Cargo.lock
@ -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",
|
||||
@ -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",
|
||||
]
|
||||
|
||||
@ -5363,7 +5369,7 @@ dependencies = [
|
||||
"dlmalloc",
|
||||
"fortanix-sgx-abi",
|
||||
"hashbrown",
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.4.0",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object 0.36.0",
|
||||
|
@ -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 }
|
||||
|
@ -1,7 +1,8 @@
|
||||
#![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;
|
||||
@ -9,6 +10,10 @@ 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,
|
||||
@ -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)
|
||||
@ -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(&[])
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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,
|
||||
}
|
||||
@ -90,7 +90,7 @@ pub struct FilePermissions {
|
||||
|
||||
#[derive(Copy, Clone, Eq, Debug)]
|
||||
pub struct FileType {
|
||||
mode: u32,
|
||||
mode: u8,
|
||||
}
|
||||
|
||||
impl PartialEq for FileType {
|
||||
@ -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 {
|
||||
@ -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()),
|
||||
};
|
||||
|
||||
@ -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)]
|
||||
@ -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<()> {
|
||||
@ -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]
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
|
@ -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()?,
|
||||
})
|
||||
});
|
||||
|
||||
|
82
library/std/src/sys/pal/hermit/io.rs
Normal file
82
library/std/src/sys/pal/hermit/io.rs
Normal file
@ -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())
|
||||
}
|
@ -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;
|
||||
|
@ -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)> {
|
||||
@ -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<()> {
|
||||
@ -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(())
|
||||
}
|
||||
|
||||
|
@ -198,5 +198,5 @@ pub fn exit(code: i32) -> ! {
|
||||
}
|
||||
|
||||
pub fn getpid() -> u32 {
|
||||
unsafe { hermit_abi::getpid() }
|
||||
unsafe { hermit_abi::getpid() as u32 }
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
use super::hermit_abi;
|
||||
use crate::io;
|
||||
use crate::io::{IoSlice, IoSliceMut};
|
||||
use crate::mem::ManuallyDrop;
|
||||
use crate::os::hermit::io::FromRawFd;
|
||||
use crate::sys::fd::FileDesc;
|
||||
|
||||
pub struct Stdin;
|
||||
pub struct Stdout;
|
||||
@ -13,12 +16,14 @@ impl Stdin {
|
||||
}
|
||||
|
||||
impl io::Read for Stdin {
|
||||
fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
|
||||
self.read_vectored(&mut [IoSliceMut::new(data)])
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read(buf) }
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
Ok(0)
|
||||
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -34,27 +39,13 @@ impl Stdout {
|
||||
}
|
||||
|
||||
impl io::Write for Stdout {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe { len = hermit_abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stdout is not able to print"))
|
||||
} else {
|
||||
Ok(len as usize)
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write(buf) }
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe { len = hermit_abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stdout is not able to print"))
|
||||
} else {
|
||||
Ok(len as usize)
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,27 +66,13 @@ impl Stderr {
|
||||
}
|
||||
|
||||
impl io::Write for Stderr {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe { len = hermit_abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stderr is not able to print"))
|
||||
} else {
|
||||
Ok(len as usize)
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write(buf) }
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
let len;
|
||||
|
||||
unsafe { len = hermit_abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
||||
|
||||
if len < 0 {
|
||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stderr is not able to print"))
|
||||
} else {
|
||||
Ok(len as usize)
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,10 +86,10 @@ impl io::Write for Stderr {
|
||||
}
|
||||
}
|
||||
|
||||
pub const STDIN_BUF_SIZE: usize = 0;
|
||||
pub const STDIN_BUF_SIZE: usize = 128;
|
||||
|
||||
pub fn is_ebadf(_err: &io::Error) -> bool {
|
||||
true
|
||||
pub fn is_ebadf(err: &io::Error) -> bool {
|
||||
err.raw_os_error() == Some(hermit_abi::EBADF)
|
||||
}
|
||||
|
||||
pub fn panic_output() -> Option<impl io::Write> {
|
||||
|
@ -98,5 +98,5 @@ impl Thread {
|
||||
}
|
||||
|
||||
pub fn available_parallelism() -> io::Result<NonZero<usize>> {
|
||||
unsafe { Ok(NonZero::new_unchecked(hermit_abi::get_processor_count())) }
|
||||
unsafe { Ok(NonZero::new_unchecked(hermit_abi::available_parallelism())) }
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::hermit_abi::{self, timespec, CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC};
|
||||
use super::hermit_abi::{self, timespec, CLOCK_MONOTONIC, CLOCK_REALTIME};
|
||||
use crate::cmp::Ordering;
|
||||
use crate::ops::{Add, AddAssign, Sub, SubAssign};
|
||||
use crate::time::Duration;
|
||||
use core::hash::{Hash, Hasher};
|
||||
|
||||
const NSEC_PER_SEC: i32 = 1_000_000_000;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct Timespec {
|
||||
t: timespec,
|
||||
@ -16,8 +18,8 @@ impl Timespec {
|
||||
Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
|
||||
}
|
||||
|
||||
const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
|
||||
assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64);
|
||||
const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec {
|
||||
assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC);
|
||||
// SAFETY: The assert above checks tv_nsec is within the valid range
|
||||
Timespec { t: timespec { tv_sec: tv_sec, tv_nsec: tv_nsec } }
|
||||
}
|
||||
@ -32,7 +34,7 @@ impl Timespec {
|
||||
} else {
|
||||
Duration::new(
|
||||
(self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
|
||||
(self.t.tv_nsec + NSEC_PER_SEC - other.t.tv_nsec) as u32,
|
||||
)
|
||||
})
|
||||
} else {
|
||||
@ -48,9 +50,9 @@ impl Timespec {
|
||||
|
||||
// Nano calculations can't overflow because nanos are <1B which fit
|
||||
// in a u32.
|
||||
let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
|
||||
if nsec >= NSEC_PER_SEC as u32 {
|
||||
nsec -= NSEC_PER_SEC as u32;
|
||||
let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
|
||||
if nsec >= NSEC_PER_SEC.try_into().unwrap() {
|
||||
nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
|
||||
secs = secs.checked_add(1)?;
|
||||
}
|
||||
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||
@ -200,7 +202,7 @@ pub struct SystemTime(Timespec);
|
||||
pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
|
||||
|
||||
impl SystemTime {
|
||||
pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime {
|
||||
pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime {
|
||||
SystemTime(Timespec::new(tv_sec, tv_nsec))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user