Add multithreading to rust code.
This commit is contained in:
parent
19144f7be9
commit
d5a5041c4b
|
@ -351,9 +351,7 @@ pub struct ZThreadStartReq {
|
||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct ZThreadExitReq {
|
pub struct ZThreadExitReq {}
|
||||||
pub _address: u8,
|
|
||||||
}
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[link_name = "\u{1}_Z11ZThreadExitv"]
|
#[link_name = "\u{1}_Z11ZThreadExitv"]
|
||||||
pub fn ZThreadExit() -> z_err_t;
|
pub fn ZThreadExit() -> z_err_t;
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
|
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
|
#[macro_use]
|
||||||
pub mod syscall;
|
pub mod syscall;
|
||||||
|
pub mod thread;
|
||||||
|
|
||||||
// From /zion/include/ztypes.h
|
// From /zion/include/ztypes.h
|
||||||
const Z_INIT_SELF_PROC: u64 = 0x4000_0000;
|
const Z_INIT_SELF_PROC: u64 = 0x4000_0000;
|
||||||
|
|
|
@ -138,10 +138,10 @@ impl fmt::Write for Writer {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! debug {
|
macro_rules! debug {
|
||||||
() => {
|
() => {
|
||||||
debug("");
|
$crate::syscall::debug("");
|
||||||
};
|
};
|
||||||
($fmt:literal) => {
|
($fmt:literal) => {
|
||||||
debug($fmt);
|
$crate::syscall::debug($fmt);
|
||||||
};
|
};
|
||||||
($fmt:literal, $($val:expr),+) => {{
|
($fmt:literal, $($val:expr),+) => {{
|
||||||
use core::fmt::Write as _;
|
use core::fmt::Write as _;
|
||||||
|
@ -149,6 +149,6 @@ macro_rules! debug {
|
||||||
let mut w = $crate::syscall::Writer::new();
|
let mut w = $crate::syscall::Writer::new();
|
||||||
write!(&mut w, $fmt, $($val),*).expect("Failed to format");
|
write!(&mut w, $fmt, $($val),*).expect("Failed to format");
|
||||||
let s: String = w.into();
|
let s: String = w.into();
|
||||||
debug(&s);
|
$crate::syscall::debug(&s);
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
use crate::syscall;
|
||||||
|
use crate::syscall::z_cap_t;
|
||||||
|
|
||||||
|
use core::ffi::c_void;
|
||||||
|
|
||||||
|
pub type ThreadEntry = fn(*const c_void) -> ();
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
extern "C" fn entry_point(entry_ptr: *const ThreadEntry, arg1: *const c_void) -> ! {
|
||||||
|
debug!("Entry {:#p} arg1 {:#x}", entry_ptr, arg1 as u64);
|
||||||
|
let entry = unsafe { *entry_ptr };
|
||||||
|
|
||||||
|
entry(arg1);
|
||||||
|
|
||||||
|
let _ = syscall::syscall(syscall::kZionThreadExit, &syscall::ZThreadExitReq {});
|
||||||
|
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add a Drop implementation that kills this thread and drops its capability.
|
||||||
|
pub struct Thread<'a> {
|
||||||
|
cap: z_cap_t,
|
||||||
|
// This field only exists to ensure that the entry reference will outlive the thread object
|
||||||
|
// itself.
|
||||||
|
_entry: &'a ThreadEntry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Thread<'a> {
|
||||||
|
pub fn spawn(entry: &'a ThreadEntry, arg1: *const c_void) -> Self {
|
||||||
|
let mut cap: z_cap_t = 0;
|
||||||
|
let req = syscall::ZThreadCreateReq {
|
||||||
|
proc_cap: unsafe { crate::SELF_PROC_CAP },
|
||||||
|
thread_cap: &mut cap as *mut z_cap_t,
|
||||||
|
};
|
||||||
|
|
||||||
|
syscall::syscall(syscall::kZionThreadCreate, &req).expect("Failed to create thread.");
|
||||||
|
|
||||||
|
syscall::syscall(
|
||||||
|
syscall::kZionThreadStart,
|
||||||
|
&syscall::ZThreadStartReq {
|
||||||
|
thread_cap: cap,
|
||||||
|
entry: entry_point as u64,
|
||||||
|
arg1: entry as *const ThreadEntry as u64,
|
||||||
|
arg2: arg1 as u64,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Failed to start thread.");
|
||||||
|
|
||||||
|
Self { cap, _entry: entry }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn join(&self) -> Result<(), syscall::ZError> {
|
||||||
|
syscall::syscall(
|
||||||
|
syscall::kZionThreadWait,
|
||||||
|
&syscall::ZThreadWaitReq {
|
||||||
|
thread_cap: self.cap,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ use mammoth::debug;
|
||||||
use mammoth::define_entry;
|
use mammoth::define_entry;
|
||||||
use mammoth::syscall::debug;
|
use mammoth::syscall::debug;
|
||||||
use mammoth::syscall::z_err_t;
|
use mammoth::syscall::z_err_t;
|
||||||
|
use mammoth::thread;
|
||||||
use yellowstone::GetEndpointRequest;
|
use yellowstone::GetEndpointRequest;
|
||||||
use yellowstone::YellowstoneClient;
|
use yellowstone::YellowstoneClient;
|
||||||
|
|
||||||
|
@ -41,5 +42,12 @@ pub extern "C" fn main() -> z_err_t {
|
||||||
|
|
||||||
debug!("Got endpoint w/ cap: {:#x}", endpoint.endpoint);
|
debug!("Got endpoint w/ cap: {:#x}", endpoint.endpoint);
|
||||||
|
|
||||||
|
let e: thread::ThreadEntry = |_| {
|
||||||
|
debug!("Testing 1 2 3");
|
||||||
|
};
|
||||||
|
let t = thread::Thread::spawn(&e, core::ptr::null());
|
||||||
|
|
||||||
|
t.join().expect("Failed to wait.");
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue