feat: add Rust userspace support; fix TLS layout for p_align < 16; kill whole process on sibling-thread faults
This commit is contained in:
1 parent
a81298fb24
commit
f8b8f9610f
31 files changed
+1076
-38
No files matched your search
@@ -0,0 +1,82 @@
|
||||
//! Terminal output. `print!`/`println!` format into a stack buffer and hand
|
||||
//! it to SYS_PRINT in NUL-terminated chunks, so one call is one (or a few)
|
||||
//! syscalls rather than libc write()'s one SYS_PUTCHAR per byte.
|
||||
|
||||
use core::fmt::{self, Write};
|
||||
|
||||
use crate::sys;
|
||||
|
||||
const CHUNK: usize = 256;
|
||||
|
||||
/// Buffered writer to the process's terminal (stdout).
|
||||
pub struct Stdout {
|
||||
buf: [u8; CHUNK],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl Stdout {
|
||||
pub const fn new() -> Self {
|
||||
Stdout { buf: [0; CHUNK], len: 0 }
|
||||
}
|
||||
|
||||
pub fn write_bytes(&mut self, bytes: &[u8]) {
|
||||
for &b in bytes {
|
||||
if b == 0 {
|
||||
// SYS_PRINT stops at NUL; send it on its own.
|
||||
self.flush();
|
||||
unsafe { sys::syscall1(sys::SYS_PUTCHAR, 0) };
|
||||
continue;
|
||||
}
|
||||
if self.len == CHUNK - 1 {
|
||||
self.flush();
|
||||
}
|
||||
self.buf[self.len] = b;
|
||||
self.len += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flush(&mut self) {
|
||||
if self.len == 0 {
|
||||
return;
|
||||
}
|
||||
self.buf[self.len] = 0;
|
||||
unsafe { sys::syscall1(sys::SYS_PRINT, self.buf.as_ptr() as u64) };
|
||||
self.len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Stdout {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Stdout {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.write_bytes(s.as_bytes());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Stdout {
|
||||
fn drop(&mut self) {
|
||||
self.flush();
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _print(args: fmt::Arguments) {
|
||||
let mut out = Stdout::new();
|
||||
let _ = out.write_fmt(args);
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => { $crate::io::_print(format_args!($($arg)*)) };
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
() => { $crate::print!("\n") };
|
||||
($($arg:tt)*) => { $crate::io::_print(format_args!("{}\n", format_args!($($arg)*))) };
|
||||
}
|
||||
Reference in new issue
Block a user