alnyan/yggdrasil: use a better allocator

This commit is contained in:
2023-12-18 14:55:49 +02:00
parent aa4283ac3b
commit 7d4c743cf1
9 changed files with 124 additions and 28 deletions
+1
View File
@@ -81,5 +81,6 @@ tests/rustdoc-gui/src/**.lock
## Yggdrasil OS ABI link
/yggdrasil-rt
/yggdrasil-abi
/libyalloc
# Before adding new lines, see the comment at the top.
+11
View File
@@ -3013,6 +3013,16 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "libyalloc"
version = "0.1.0"
dependencies = [
"compiler_builtins",
"libc",
"rustc-std-workspace-core",
"yggdrasil-rt",
]
[[package]]
name = "libz-sys"
version = "1.1.3"
@@ -6011,6 +6021,7 @@ dependencies = [
"hashbrown 0.12.3",
"hermit-abi 0.3.0",
"libc",
"libyalloc",
"miniz_oxide",
"object 0.29.0",
"panic_abort",
+2
View File
@@ -123,3 +123,5 @@ clippy_lints = { path = "src/tools/clippy/clippy_lints" }
yggdrasil-rt = { path = "yggdrasil-rt" }
[patch."https://git.alnyan.me/yggdrasil/yggdrasil-abi.git"]
yggdrasil-abi = { path = "yggdrasil-abi" }
[patch."https://git.alnyan.me/yggdrasil/libyalloc.git"]
libyalloc = { path = "libyalloc" }
+1
View File
@@ -47,6 +47,7 @@ hermit-abi = { version = "0.3.0", features = ['rustc-dep-of-std'] }
[target.'cfg(target_os = "yggdrasil")'.dependencies]
yggdrasil-rt = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-rt.git", features = ['rustc-dep-of-std'] }
libyalloc = { git = "https://git.alnyan.me/yggdrasil/libyalloc.git", features = ['rustc-dep-of-std'] }
[target.wasm32-wasi.dependencies]
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
+9
View File
@@ -88,6 +88,15 @@ pub unsafe fn mount_raw(options: &MountOptions<'_>) -> crate::io::Result<()> {
cvt_io(syscall::mount(options))
}
#[unstable(feature = "yggdrasil_os", issue = "none")]
pub fn create_pipe_pair() -> crate::io::Result<(RawFd, RawFd)> {
let mut buffer = MaybeUninit::uninit_array();
cvt_io(unsafe { syscall::create_pipe(&mut buffer) })?;
let read = unsafe { buffer[0].assume_init() };
let write = unsafe { buffer[1].assume_init() };
Ok((read, write))
}
#[unstable(feature = "yggdrasil_os", issue = "none")]
pub unsafe fn update_terminal_options<
F: raw::AsRawFd,
+1
View File
@@ -92,6 +92,7 @@ impl AsRawFd for OwnedFd {
#[stable(feature = "io_safety", since = "1.63.0")]
impl Drop for OwnedFd {
fn drop(&mut self) {
yggdrasil_rt::debug_trace!("--- OwnedFd drop: {:?} ---", self.fd);
unsafe {
yggdrasil_rt::sys::close(self.fd).ok();
}
+9 -10
View File
@@ -1,24 +1,23 @@
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr::NonNull;
use crate::sync::Mutex;
use libyalloc::Allocator;
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
yggdrasil_rt::alloc::malloc(layout)
}
let ptr = ALLOC.lock().expect("Could not lock allocator mutex").alloc(layout);
#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
yggdrasil_rt::alloc::malloc_zeroed(layout)
if let Some(ptr) = ptr { ptr.as_ptr() } else { crate::ptr::null_mut() }
}
#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
yggdrasil_rt::alloc::dealloc(ptr, layout)
}
let ptr = NonNull::new(ptr).expect("Invalid pointer");
#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
yggdrasil_rt::alloc::realloc(ptr, layout, new_size)
ALLOC.lock().expect("Could not lock allocator mutex").free(ptr, layout);
}
}
static ALLOC: Mutex<Allocator> = Mutex::new(Allocator::new());
+33 -10
View File
@@ -1,38 +1,61 @@
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, RawFd};
use crate::sys::cvt_io;
use crate::sys::io::FileDesc;
pub struct AnonPipe(!);
pub struct AnonPipe(FileDesc);
impl AnonPipe {
pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
self.0
todo!()
}
pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
self.0
todo!()
}
pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
self.0
todo!()
}
pub fn is_read_vectored(&self) -> bool {
self.0
false
}
pub fn read_to_end(&self, _buf: &mut Vec<u8>) -> io::Result<usize> {
self.0
todo!()
}
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
self.0
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
unsafe { cvt_io(yggdrasil_rt::sys::write(self.as_raw_fd(), buf)) }
}
pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result<usize> {
self.0
todo!()
}
pub fn is_write_vectored(&self) -> bool {
self.0
todo!()
}
}
impl FromRawFd for AnonPipe {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
Self(FileDesc::from_raw_fd(fd))
}
}
impl AsRawFd for AnonPipe {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl Drop for AnonPipe {
fn drop(&mut self) {
unsafe {
// yggdrasil_rt::sys::close(self.as_raw_fd()).ok();
}
}
}
+57 -8
View File
@@ -2,11 +2,14 @@ use crate::ffi::OsStr;
use crate::fmt;
use crate::io;
use crate::num::NonZeroI32;
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, IntoRawFd};
use crate::path::Path;
use crate::sys::cvt_io;
use crate::sys::fd::FileDesc;
use crate::sys::fs::File;
use crate::sys::pipe::AnonPipe;
use crate::sys_common::process::{CommandEnv, CommandEnvs};
use crate::sys_common::FromInner;
pub use crate::ffi::OsString as EnvKey;
@@ -36,6 +39,7 @@ pub struct ChildPipes {
pub enum ChildStdio {
Inherit,
Null,
Fd(RawFd),
}
#[derive(Debug)]
@@ -43,6 +47,7 @@ pub enum Stdio {
Inherit,
Null,
MakePipe,
Fd(FileDesc),
}
pub struct Process {
@@ -69,12 +74,44 @@ impl Process {
}
}
#[allow(ineffective_unstable_trait_impl)]
#[unstable(feature = "yggdrasil_os", issue = "none")]
impl FromRawFd for crate::process::Stdio {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> crate::process::Stdio {
let fd = FileDesc::from_raw_fd(fd);
let io = Stdio::Fd(fd);
crate::process::Stdio::from_inner(io)
}
}
impl Stdio {
pub fn to_child_stdio(&self, _readable: bool) -> io::Result<(ChildStdio, Option<AnonPipe>)> {
match *self {
pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option<AnonPipe>)> {
match self {
Stdio::Inherit => Ok((ChildStdio::Inherit, None)),
Stdio::MakePipe => todo!(),
Stdio::Null => Ok((ChildStdio::Null, None)),
Stdio::MakePipe => {
let (read, write) = crate::os::yggdrasil::io::create_pipe_pair()?;
if readable {
yggdrasil_rt::debug_trace!(
"--- Make pipes for MakePipe: to_child={:?}, to_parent={:?} ---",
read,
write
);
let write = unsafe { AnonPipe::from_raw_fd(write) };
Ok((ChildStdio::Fd(read), Some(write)))
} else {
yggdrasil_rt::debug_trace!(
"--- Make pipes for MakePipe: to_child={:?}, to_parent={:?} ---",
write,
read
);
let read = unsafe { AnonPipe::from_raw_fd(read) };
Ok((ChildStdio::Fd(write), Some(read)))
}
}
Stdio::Fd(fd) => Ok((ChildStdio::Fd(fd.as_raw_fd()), None)),
}
}
}
@@ -203,6 +240,7 @@ impl Command {
}
pub fn stdin(&mut self, stdin: Stdio) {
yggdrasil_rt::debug_trace!("!!! Override stdin: {:?}", stdin);
self.stdin = stdin;
}
@@ -235,12 +273,21 @@ impl Command {
default: Stdio,
needs_stdin: bool,
) -> io::Result<(Process, StdioPipes)> {
yggdrasil_rt::debug_trace!("Default: {:?}, needs_stdin = {:?}", default, needs_stdin);
let default_stdin = if needs_stdin { &default } else { &self.stdin };
let stdin = default_stdin;
let stdin = &self.stdin;
let stdout = &self.stdout;
let stderr = &self.stderr;
yggdrasil_rt::debug_trace!(
"stdin = {:?}, stdout = {:?}, stderr = {:?}",
stdin,
stdout,
stderr
);
let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?;
let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
@@ -266,7 +313,8 @@ impl Command {
optional.push(SpawnOption::InheritFile {
source: match pipes.stdin {
ChildStdio::Inherit => RawFd::STDIN,
ChildStdio::Null => unreachable!(),
ChildStdio::Fd(fd) => fd,
ChildStdio::Null => todo!(),
},
child: RawFd::STDIN,
});
@@ -275,7 +323,8 @@ impl Command {
optional.push(SpawnOption::InheritFile {
source: match pipes.stdout {
ChildStdio::Inherit => RawFd::STDOUT,
ChildStdio::Null => unreachable!(),
ChildStdio::Fd(fd) => fd,
ChildStdio::Null => todo!(),
},
child: RawFd::STDOUT,
});
@@ -284,7 +333,8 @@ impl Command {
optional.push(SpawnOption::InheritFile {
source: match pipes.stderr {
ChildStdio::Inherit => RawFd::STDERR,
ChildStdio::Null => unreachable!(),
ChildStdio::Fd(fd) => fd,
ChildStdio::Null => todo!(),
},
child: RawFd::STDERR,
});
@@ -317,7 +367,6 @@ impl Command {
}));
let environment = &Vec::from_iter(envs.iter().map(|x| x.as_str()));
yggdrasil_rt::debug_trace!("env = {:#?}", environment);
let options = SpawnOptions { program, arguments, environment, optional: &optional };