alnyan/yggdrasil: thread+static TLS, mutex+condvar impl
This commit is contained in:
@@ -16,6 +16,8 @@ SECTIONS {
|
|||||||
|
|
||||||
.rodata : {
|
.rodata : {
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
|
/* TODO: this is unused currently */
|
||||||
|
*(.eh_frame*)
|
||||||
}
|
}
|
||||||
|
|
||||||
. = ALIGN(4K);
|
. = ALIGN(4K);
|
||||||
@@ -31,4 +33,10 @@ SECTIONS {
|
|||||||
*(COMMON)
|
*(COMMON)
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
. = ALIGN(4K);
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
*(.tbss*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ SECTIONS {
|
|||||||
|
|
||||||
.rodata : {
|
.rodata : {
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
|
/* TODO: this is unused currently */
|
||||||
|
*(.eh_frame*)
|
||||||
}
|
}
|
||||||
|
|
||||||
. = ALIGN(4K);
|
. = ALIGN(4K);
|
||||||
@@ -29,4 +31,10 @@ SECTIONS {
|
|||||||
*(COMMON)
|
*(COMMON)
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
. = ALIGN(4K);
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
*(.tbss*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ pub fn opts() -> TargetOptions {
|
|||||||
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
|
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
|
||||||
lld_flavor_json: LldFlavor::Ld,
|
lld_flavor_json: LldFlavor::Ld,
|
||||||
stack_probes: StackProbeType::Inline,
|
stack_probes: StackProbeType::Inline,
|
||||||
|
has_thread_local: true,
|
||||||
max_atomic_width: Some(128),
|
max_atomic_width: Some(128),
|
||||||
eh_frame_header: false,
|
eh_frame_header: false,
|
||||||
relocation_model: RelocModel::Static,
|
relocation_model: RelocModel::Static,
|
||||||
|
|||||||
@@ -1,297 +0,0 @@
|
|||||||
#![stable(feature = "os_fd", since = "1.66.0")]
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use crate::mem::MaybeUninit;
|
|
||||||
use crate::sys::cvt_io;
|
|
||||||
use yggdrasil_rt::sys as syscall;
|
|
||||||
|
|
||||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
||||||
pub use yggdrasil_rt::io::{
|
|
||||||
DeviceRequest, TerminalInputOptions, TerminalLineOptions, TerminalOptions,
|
|
||||||
TerminalOutputOptions,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
||||||
pub trait FdDeviceRequest {
|
|
||||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
||||||
unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
||||||
impl<T: AsRawFd> FdDeviceRequest for T {
|
|
||||||
unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()> {
|
|
||||||
cvt_io(syscall::device_request(self.as_raw_fd(), req))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
||||||
pub unsafe fn set_terminal_options<F: raw::AsRawFd>(
|
|
||||||
fd: F,
|
|
||||||
opt: TerminalOptions,
|
|
||||||
) -> crate::io::Result<()> {
|
|
||||||
let mut req = DeviceRequest::SetTerminalOptions(opt);
|
|
||||||
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
||||||
pub unsafe fn get_terminal_options<F: raw::AsRawFd>(fd: F) -> crate::io::Result<TerminalOptions> {
|
|
||||||
let mut req = DeviceRequest::GetTerminalOptions(MaybeUninit::uninit());
|
|
||||||
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))?;
|
|
||||||
let DeviceRequest::GetTerminalOptions(opt) = req else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
Ok(opt.assume_init())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
||||||
pub unsafe fn update_terminal_options<
|
|
||||||
F: raw::AsRawFd,
|
|
||||||
M: Fn(TerminalOptions) -> TerminalOptions,
|
|
||||||
>(
|
|
||||||
fd: F,
|
|
||||||
mutator: M,
|
|
||||||
) -> crate::io::Result<TerminalOptions> {
|
|
||||||
let fd = fd.as_raw_fd();
|
|
||||||
let old = get_terminal_options(fd)?;
|
|
||||||
let new = mutator(old);
|
|
||||||
set_terminal_options(fd, new)?;
|
|
||||||
Ok(old)
|
|
||||||
}
|
|
||||||
|
|
||||||
mod net {
|
|
||||||
use crate::os::yggdrasil::io::OwnedFd;
|
|
||||||
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
|
||||||
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
|
|
||||||
use crate::{net, sys};
|
|
||||||
|
|
||||||
macro_rules! impl_as_raw_fd {
|
|
||||||
($($t:ident)*) => {$(
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl AsRawFd for net::$t {
|
|
||||||
#[inline]
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
self.as_inner().socket().as_raw_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_from_raw_fd {
|
|
||||||
($($t:ident)*) => {$(
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl FromRawFd for net::$t {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
|
|
||||||
let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
|
|
||||||
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_into_raw_fd {
|
|
||||||
($($t:ident)*) => {$(
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl IntoRawFd for net::$t {
|
|
||||||
#[inline]
|
|
||||||
fn into_raw_fd(self) -> RawFd {
|
|
||||||
self.into_inner().into_socket().into_inner().into_raw_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_as_raw_fd! { TcpStream TcpListener UdpSocket }
|
|
||||||
impl_from_raw_fd! { TcpStream TcpListener UdpSocket }
|
|
||||||
impl_into_raw_fd! { TcpStream TcpListener UdpSocket }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "os_fd", since = "1.66.0")]
|
|
||||||
pub(crate) mod raw {
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub type RawFd = yggdrasil_rt::io::RawFd;
|
|
||||||
|
|
||||||
macro_rules! stdio_impl_as_raw_fd {
|
|
||||||
($($ty:ty => $n:expr),*) => {$(
|
|
||||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
|
||||||
impl AsRawFd for $ty {
|
|
||||||
#[inline]
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
$n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
|
||||||
impl AsRawFd for &$ty {
|
|
||||||
#[inline]
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
$n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub trait AsRawFd {
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
fn as_raw_fd(&self) -> RawFd;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub trait FromRawFd {
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub trait IntoRawFd {
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
fn into_raw_fd(self) -> RawFd;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl AsRawFd for RawFd {
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl FromRawFd for RawFd {
|
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
|
||||||
fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl IntoRawFd for RawFd {
|
|
||||||
fn into_raw_fd(self) -> RawFd {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stdio_impl_as_raw_fd!(
|
|
||||||
crate::io::Stdin => RawFd::STDIN,
|
|
||||||
crate::io::Stdout => RawFd::STDOUT,
|
|
||||||
crate::io::Stderr => RawFd::STDERR
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod owned {
|
|
||||||
#![stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
|
|
||||||
use super::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
|
||||||
use crate::marker::PhantomData;
|
|
||||||
use crate::mem::forget;
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct OwnedFd {
|
|
||||||
fd: RawFd,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct BorrowedFd<'fd> {
|
|
||||||
fd: RawFd,
|
|
||||||
_pd: PhantomData<&'fd OwnedFd>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
pub trait AsFd {
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
fn as_fd(&self) -> BorrowedFd<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl<T: AsFd> AsFd for &T {
|
|
||||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
|
||||||
T::as_fd(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Borrowed
|
|
||||||
|
|
||||||
impl BorrowedFd<'_> {
|
|
||||||
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
pub const unsafe fn borrow_raw(fd: RawFd) -> Self {
|
|
||||||
// assert_ne!(fd, u32::MAX as RawFd);
|
|
||||||
Self { fd, _pd: PhantomData }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl AsFd for BorrowedFd<'_> {
|
|
||||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl AsRawFd for BorrowedFd<'_> {
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
self.fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Owned
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl AsFd for OwnedFd {
|
|
||||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
|
||||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl IntoRawFd for OwnedFd {
|
|
||||||
fn into_raw_fd(self) -> RawFd {
|
|
||||||
let fd = self.fd;
|
|
||||||
forget(self);
|
|
||||||
fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl FromRawFd for OwnedFd {
|
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
|
||||||
Self { fd }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl AsRawFd for OwnedFd {
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
self.fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
impl Drop for OwnedFd {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
yggdrasil_rt::sys::close(self.fd).ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: AsFd for File, From<File> for OwnedFd, From<OwnedFd> for File,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
||||||
pub use owned::*;
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use raw::*;
|
|
||||||
|
|
||||||
use crate::io::StdinLock;
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl<'a> AsRawFd for StdinLock<'a> {
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#![stable(feature = "os_fd", since = "1.66.0")]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
mod net;
|
||||||
|
pub mod owned;
|
||||||
|
pub(crate) mod raw;
|
||||||
|
|
||||||
|
use crate::io::StdinLock;
|
||||||
|
|
||||||
|
use crate::mem::MaybeUninit;
|
||||||
|
use crate::sys::cvt_io;
|
||||||
|
use yggdrasil_rt::sys as syscall;
|
||||||
|
|
||||||
|
// Public exports
|
||||||
|
|
||||||
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||||
|
pub use yggdrasil_rt::io::{
|
||||||
|
DeviceRequest, TerminalInputOptions, TerminalLineOptions, TerminalOptions,
|
||||||
|
TerminalOutputOptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
pub use owned::*;
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use raw::*;
|
||||||
|
|
||||||
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||||
|
pub trait FdDeviceRequest {
|
||||||
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||||
|
unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||||
|
impl<T: AsRawFd> FdDeviceRequest for T {
|
||||||
|
unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()> {
|
||||||
|
cvt_io(syscall::device_request(self.as_raw_fd(), req))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl<'a> AsRawFd for StdinLock<'a> {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||||
|
pub unsafe fn set_terminal_options<F: raw::AsRawFd>(
|
||||||
|
fd: F,
|
||||||
|
opt: TerminalOptions,
|
||||||
|
) -> crate::io::Result<()> {
|
||||||
|
let mut req = DeviceRequest::SetTerminalOptions(opt);
|
||||||
|
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||||
|
pub unsafe fn get_terminal_options<F: raw::AsRawFd>(fd: F) -> crate::io::Result<TerminalOptions> {
|
||||||
|
let mut req = DeviceRequest::GetTerminalOptions(MaybeUninit::uninit());
|
||||||
|
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))?;
|
||||||
|
let DeviceRequest::GetTerminalOptions(opt) = req else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
Ok(opt.assume_init())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||||
|
pub unsafe fn update_terminal_options<
|
||||||
|
F: raw::AsRawFd,
|
||||||
|
M: Fn(TerminalOptions) -> TerminalOptions,
|
||||||
|
>(
|
||||||
|
fd: F,
|
||||||
|
mutator: M,
|
||||||
|
) -> crate::io::Result<TerminalOptions> {
|
||||||
|
let fd = fd.as_raw_fd();
|
||||||
|
let old = get_terminal_options(fd)?;
|
||||||
|
let new = mutator(old);
|
||||||
|
set_terminal_options(fd, new)?;
|
||||||
|
Ok(old)
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
use crate::os::yggdrasil::io::OwnedFd;
|
||||||
|
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||||
|
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
|
||||||
|
use crate::{net, sys};
|
||||||
|
|
||||||
|
macro_rules! impl_as_raw_fd {
|
||||||
|
($($t:ident)*) => {$(
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl AsRawFd for net::$t {
|
||||||
|
#[inline]
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.as_inner().socket().as_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_from_raw_fd {
|
||||||
|
($($t:ident)*) => {$(
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl FromRawFd for net::$t {
|
||||||
|
#[inline]
|
||||||
|
unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
|
||||||
|
let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
|
||||||
|
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_into_raw_fd {
|
||||||
|
($($t:ident)*) => {$(
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl IntoRawFd for net::$t {
|
||||||
|
#[inline]
|
||||||
|
fn into_raw_fd(self) -> RawFd {
|
||||||
|
self.into_inner().into_socket().into_inner().into_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_as_raw_fd! { TcpStream TcpListener UdpSocket }
|
||||||
|
impl_from_raw_fd! { TcpStream TcpListener UdpSocket }
|
||||||
|
impl_into_raw_fd! { TcpStream TcpListener UdpSocket }
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#![stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
|
||||||
|
use super::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||||
|
use crate::marker::PhantomData;
|
||||||
|
use crate::mem::forget;
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct OwnedFd {
|
||||||
|
fd: RawFd,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct BorrowedFd<'fd> {
|
||||||
|
fd: RawFd,
|
||||||
|
_pd: PhantomData<&'fd OwnedFd>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
pub trait AsFd {
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
fn as_fd(&self) -> BorrowedFd<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl<T: AsFd> AsFd for &T {
|
||||||
|
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||||
|
T::as_fd(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Borrowed
|
||||||
|
|
||||||
|
impl BorrowedFd<'_> {
|
||||||
|
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
pub const unsafe fn borrow_raw(fd: RawFd) -> Self {
|
||||||
|
// assert_ne!(fd, u32::MAX as RawFd);
|
||||||
|
Self { fd, _pd: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl AsFd for BorrowedFd<'_> {
|
||||||
|
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl AsRawFd for BorrowedFd<'_> {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.fd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Owned
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl AsFd for OwnedFd {
|
||||||
|
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||||
|
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl IntoRawFd for OwnedFd {
|
||||||
|
fn into_raw_fd(self) -> RawFd {
|
||||||
|
let fd = self.fd;
|
||||||
|
forget(self);
|
||||||
|
fd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl FromRawFd for OwnedFd {
|
||||||
|
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
||||||
|
Self { fd }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl AsRawFd for OwnedFd {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.fd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||||
|
impl Drop for OwnedFd {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
yggdrasil_rt::sys::close(self.fd).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: AsFd for File, From<File> for OwnedFd, From<OwnedFd> for File,
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#![stable(feature = "os_fd", since = "1.66.0")]
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub type RawFd = yggdrasil_rt::io::RawFd;
|
||||||
|
|
||||||
|
macro_rules! stdio_impl_as_raw_fd {
|
||||||
|
($($ty:ty => $n:expr),*) => {$(
|
||||||
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
|
impl AsRawFd for $ty {
|
||||||
|
#[inline]
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
$n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||||
|
impl AsRawFd for &$ty {
|
||||||
|
#[inline]
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
$n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub trait AsRawFd {
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
fn as_raw_fd(&self) -> RawFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub trait FromRawFd {
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
unsafe fn from_raw_fd(fd: RawFd) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub trait IntoRawFd {
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
fn into_raw_fd(self) -> RawFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl AsRawFd for RawFd {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl FromRawFd for RawFd {
|
||||||
|
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
||||||
|
fd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl IntoRawFd for RawFd {
|
||||||
|
fn into_raw_fd(self) -> RawFd {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stdio_impl_as_raw_fd!(
|
||||||
|
crate::io::Stdin => RawFd::STDIN,
|
||||||
|
crate::io::Stdout => RawFd::STDOUT,
|
||||||
|
crate::io::Stderr => RawFd::STDERR
|
||||||
|
);
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
mod condvar {
|
|
||||||
use crate::sys::locks::Mutex;
|
|
||||||
use crate::time::Duration;
|
|
||||||
|
|
||||||
pub struct Condvar {}
|
|
||||||
|
|
||||||
impl Condvar {
|
|
||||||
#[inline]
|
|
||||||
#[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
|
|
||||||
pub const fn new() -> Condvar {
|
|
||||||
Condvar {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn notify_one(&self) {}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn notify_all(&self) {}
|
|
||||||
|
|
||||||
pub unsafe fn wait(&self, _mutex: &Mutex) {
|
|
||||||
panic!("condvar wait not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
|
|
||||||
panic!("condvar wait not supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod mutex {
|
|
||||||
use crate::cell::Cell;
|
|
||||||
|
|
||||||
pub struct Mutex {
|
|
||||||
// This platform has no threads, so we can use a Cell here.
|
|
||||||
locked: Cell<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for Mutex {}
|
|
||||||
unsafe impl Sync for Mutex {} // no threads on this platform
|
|
||||||
|
|
||||||
impl Mutex {
|
|
||||||
#[inline]
|
|
||||||
#[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
|
|
||||||
pub const fn new() -> Mutex {
|
|
||||||
Mutex { locked: Cell::new(false) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn lock(&self) {
|
|
||||||
assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn unlock(&self) {
|
|
||||||
self.locked.set(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn try_lock(&self) -> bool {
|
|
||||||
self.locked.replace(true) == false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod rwlock {
|
|
||||||
use crate::cell::Cell;
|
|
||||||
|
|
||||||
pub struct RwLock {
|
|
||||||
// This platform has no threads, so we can use a Cell here.
|
|
||||||
mode: Cell<isize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for RwLock {}
|
|
||||||
unsafe impl Sync for RwLock {} // no threads on this platform
|
|
||||||
|
|
||||||
impl RwLock {
|
|
||||||
#[inline]
|
|
||||||
#[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
|
|
||||||
pub const fn new() -> RwLock {
|
|
||||||
RwLock { mode: Cell::new(0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn read(&self) {
|
|
||||||
let m = self.mode.get();
|
|
||||||
if m >= 0 {
|
|
||||||
self.mode.set(m + 1);
|
|
||||||
} else {
|
|
||||||
rtabort!("rwlock locked for writing");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn try_read(&self) -> bool {
|
|
||||||
let m = self.mode.get();
|
|
||||||
if m >= 0 {
|
|
||||||
self.mode.set(m + 1);
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn write(&self) {
|
|
||||||
if self.mode.replace(-1) != 0 {
|
|
||||||
rtabort!("rwlock locked for reading")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn try_write(&self) -> bool {
|
|
||||||
if self.mode.get() == 0 {
|
|
||||||
self.mode.set(-1);
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn read_unlock(&self) {
|
|
||||||
self.mode.set(self.mode.get() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn write_unlock(&self) {
|
|
||||||
assert_eq!(self.mode.replace(0), -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use condvar::Condvar;
|
|
||||||
pub use mutex::Mutex;
|
|
||||||
pub use rwlock::RwLock;
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
use crate::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
use crate::sys::locks::Mutex;
|
||||||
|
use crate::time::Duration;
|
||||||
|
use yggdrasil_rt::{process::MutexOperation, sys};
|
||||||
|
|
||||||
|
pub struct Condvar {
|
||||||
|
value: AtomicU32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Condvar {
|
||||||
|
#[inline]
|
||||||
|
#[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
|
||||||
|
pub const fn new() -> Condvar {
|
||||||
|
Condvar { value: AtomicU32::new(0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn notify_one(&self) {
|
||||||
|
self.value.fetch_add(1, Ordering::Release);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
sys::mutex(&self.value, &MutexOperation::Wake).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn notify_all(&self) {
|
||||||
|
self.value.fetch_add(1, Ordering::Release);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
sys::mutex(&self.value, &MutexOperation::WakeAll).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn wait(&self, mutex: &Mutex) {
|
||||||
|
// Load the old value while the lock is still held
|
||||||
|
let compare_value = self.value.load(Ordering::Acquire);
|
||||||
|
|
||||||
|
// Release the lock so others can now access the value
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
// Wait for the value to change
|
||||||
|
self.wait_inner(compare_value, None);
|
||||||
|
|
||||||
|
// Re-lock the mutex
|
||||||
|
mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
|
||||||
|
// Load the old value while the lock is still held
|
||||||
|
let compare_value = self.value.load(Ordering::Acquire);
|
||||||
|
|
||||||
|
// Release the lock so others can now access the value
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
// Wait for the value to change
|
||||||
|
let r = self.wait_inner(compare_value, Some(dur));
|
||||||
|
|
||||||
|
// Re-lock the mutex
|
||||||
|
mutex.lock();
|
||||||
|
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn wait_inner(&self, value: u32, timeout: Option<Duration>) -> bool {
|
||||||
|
sys::mutex(&self.value, &MutexOperation::Wait(value, timeout)).is_ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
mod condvar;
|
||||||
|
mod mutex;
|
||||||
|
mod rwlock;
|
||||||
|
|
||||||
|
pub use condvar::Condvar;
|
||||||
|
pub use mutex::Mutex;
|
||||||
|
pub use rwlock::RwLock;
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
use crate::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
use crate::time::Duration;
|
||||||
|
use yggdrasil_rt::{process::MutexOperation, sys};
|
||||||
|
|
||||||
|
pub struct Mutex {
|
||||||
|
value: AtomicU32,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Mutex {}
|
||||||
|
unsafe impl Sync for Mutex {} // no threads on this platform
|
||||||
|
|
||||||
|
impl Mutex {
|
||||||
|
const UNLOCKED: u32 = 0;
|
||||||
|
const LOCKED: u32 = 1;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
|
||||||
|
pub const fn new() -> Mutex {
|
||||||
|
Mutex { value: AtomicU32::new(Self::UNLOCKED) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn lock(&self) {
|
||||||
|
loop {
|
||||||
|
if self.try_lock() {
|
||||||
|
// Got a lock!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until the value becomes something other than "1" (0)
|
||||||
|
self.wait(Self::LOCKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn unlock(&self) {
|
||||||
|
if self.value.swap(Self::UNLOCKED, Ordering::Release) != Self::UNLOCKED {
|
||||||
|
self.wake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn try_lock(&self) -> bool {
|
||||||
|
self.value
|
||||||
|
.compare_exchange(Self::UNLOCKED, Self::LOCKED, Ordering::Acquire, Ordering::Relaxed)
|
||||||
|
.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait(&self, value: u32) {
|
||||||
|
unsafe {
|
||||||
|
sys::mutex(&self.value, &MutexOperation::Wait(value, None)).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake(&self) {
|
||||||
|
unsafe {
|
||||||
|
sys::mutex(&self.value, &MutexOperation::Wake).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
use crate::cell::Cell;
|
||||||
|
|
||||||
|
pub struct RwLock {
|
||||||
|
mode: Cell<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for RwLock {}
|
||||||
|
unsafe impl Sync for RwLock {} // no threads on this platform
|
||||||
|
|
||||||
|
impl RwLock {
|
||||||
|
#[inline]
|
||||||
|
#[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
|
||||||
|
pub const fn new() -> RwLock {
|
||||||
|
RwLock { mode: Cell::new(0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn read(&self) {
|
||||||
|
let m = self.mode.get();
|
||||||
|
if m >= 0 {
|
||||||
|
self.mode.set(m + 1);
|
||||||
|
} else {
|
||||||
|
rtabort!("rwlock locked for writing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn try_read(&self) -> bool {
|
||||||
|
let m = self.mode.get();
|
||||||
|
if m >= 0 {
|
||||||
|
self.mode.set(m + 1);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn write(&self) {
|
||||||
|
if self.mode.replace(-1) != 0 {
|
||||||
|
rtabort!("rwlock locked for reading")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn try_write(&self) -> bool {
|
||||||
|
if self.mode.get() == 0 {
|
||||||
|
self.mode.set(-1);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn read_unlock(&self) {
|
||||||
|
self.mode.set(self.mode.get() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn write_unlock(&self) {
|
||||||
|
assert_eq!(self.mode.replace(0), -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ pub mod pipe;
|
|||||||
pub mod process;
|
pub mod process;
|
||||||
pub mod stdio;
|
pub mod stdio;
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
|
pub mod thread_local_dtor;
|
||||||
pub mod thread_local_key;
|
pub mod thread_local_key;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,32 @@
|
|||||||
use crate::ffi::CStr;
|
use crate::ffi::CStr;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::num::NonZeroUsize;
|
use crate::num::NonZeroUsize;
|
||||||
|
use crate::sys::cvt_io;
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
|
|
||||||
pub struct Thread(!);
|
use yggdrasil_rt::{process::ThreadSpawnOptions, sys};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Thread {
|
||||||
|
id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
pub const DEFAULT_MIN_STACK_SIZE: usize = 8192;
|
pub const DEFAULT_MIN_STACK_SIZE: usize = 8192;
|
||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
pub unsafe fn new(stack_size: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||||
yggdrasil_rt::sys::debug_trace("Thread::new()");
|
// Allocate the stack
|
||||||
loop {}
|
let (stack_bottom, _, _) = Vec::into_raw_parts(vec![0u8; stack_size]);
|
||||||
|
let stack_bottom = stack_bottom.addr();
|
||||||
|
let stack_top = stack_bottom + stack_size - 8;
|
||||||
|
|
||||||
|
// Get the "argument"
|
||||||
|
let argument = Box::into_raw(Box::new(p)).addr() as u64;
|
||||||
|
|
||||||
|
let options = ThreadSpawnOptions { entry: Thread::entry, argument, stack_top };
|
||||||
|
let id = cvt_io(sys::spawn_thread(&options))?;
|
||||||
|
|
||||||
|
Ok(Thread { id })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn yield_now() {
|
pub fn yield_now() {
|
||||||
@@ -35,6 +51,21 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn entry(arg: u64) -> ! {
|
||||||
|
use yggdrasil_rt::{debug_trace, process::ExitCode, sys};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
#[allow(fuzzy_provenance_casts)]
|
||||||
|
let p: Box<Box<dyn FnOnce()>> = Box::from_raw(arg as *mut _);
|
||||||
|
|
||||||
|
debug_trace!("Execute thread");
|
||||||
|
p();
|
||||||
|
debug_trace!("Thread finish");
|
||||||
|
|
||||||
|
sys::exit(ExitCode::Exited(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn available_parallelism() -> io::Result<NonZeroUsize> {
|
pub fn available_parallelism() -> io::Result<NonZeroUsize> {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
||||||
|
yggdrasil_rt::debug_trace!("TODO: thread_local_dtor::register_dtor()");
|
||||||
|
|
||||||
|
// From *nix impl:
|
||||||
|
//
|
||||||
|
// use crate::mem;
|
||||||
|
// use crate::sys_common::thread_local_dtor::register_dtor_fallback;
|
||||||
|
|
||||||
|
// extern "C" {
|
||||||
|
// #[linkage = "extern_weak"]
|
||||||
|
// static __dso_handle: *mut u8;
|
||||||
|
// #[linkage = "extern_weak"]
|
||||||
|
// static __cxa_thread_atexit_impl: *const libc::c_void;
|
||||||
|
// }
|
||||||
|
// if !__cxa_thread_atexit_impl.is_null() {
|
||||||
|
// type F = unsafe extern "C" fn(
|
||||||
|
// dtor: unsafe extern "C" fn(*mut u8),
|
||||||
|
// arg: *mut u8,
|
||||||
|
// dso_handle: *mut u8,
|
||||||
|
// ) -> libc::c_int;
|
||||||
|
// mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)(
|
||||||
|
// dtor,
|
||||||
|
// t,
|
||||||
|
// &__dso_handle as *const _ as *mut _,
|
||||||
|
// );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// register_dtor_fallback(t, dtor);
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ impl LocalKey {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
||||||
|
yggdrasil_rt::debug_trace!("LocalKey::create()");
|
||||||
let boxed = Box::new(LocalKey::new(dtor));
|
let boxed = Box::new(LocalKey::new(dtor));
|
||||||
let key = Box::into_raw(boxed);
|
let key = Box::into_raw(boxed);
|
||||||
key as usize
|
key as usize
|
||||||
|
|||||||
+1
-1
Submodule yggdrasil-rt updated: f00ecdb926...87874745c0
Reference in New Issue
Block a user