| use crate::ffi::CStr; | |
| use crate::io; | |
| use crate::num::NonZeroUsize; | |
| use crate::sys::map_motor_error; | |
| use crate::thread::ThreadInit; | |
| use crate::time::{Duration, Instant}; | |
| pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 256; | |
| pub struct Thread { | |
| sys_thread: moto_rt::thread::ThreadHandle, | |
| } | |
| unsafe impl Send for Thread {} | |
| unsafe impl Sync for Thread {} | |
| impl Thread { | |
| pub unsafe fn new(stack: usize, init: Box<ThreadInit>) -> io::Result<Thread> { | |
| extern "C" fn __moto_rt_thread_fn(thread_arg: u64) { | |
| unsafe { | |
| let init = Box::from_raw(core::ptr::with_exposed_provenance_mut::<ThreadInit>( | |
| thread_arg as usize, | |
| )); | |
| let rust_start = init.init(); | |
| if let Some(name) = crate::thread::current().name() { | |
| let _ = moto_rt::thread::set_name(name); | |
| } | |
| rust_start(); | |
| } | |
| } | |
| let thread_arg = Box::into_raw(init).expose_provenance() as u64; | |
| let sys_thread = moto_rt::thread::spawn(__moto_rt_thread_fn, stack, thread_arg) | |
| .map_err(map_motor_error)?; | |
| Ok(Self { sys_thread }) | |
| } | |
| pub fn join(self) { | |
| assert!(moto_rt::thread::join(self.sys_thread).is_ok()) | |
| } | |
| } | |
| pub fn set_name(name: &CStr) { | |
| let bytes = name.to_bytes(); | |
| if let Ok(s) = core::str::from_utf8(bytes) { | |
| let _ = moto_rt::thread::set_name(s); | |
| } | |
| } | |
| pub fn current_os_id() -> Option<u64> { | |
| None | |
| } | |
| pub fn available_parallelism() -> io::Result<NonZeroUsize> { | |
| Ok(unsafe { NonZeroUsize::new_unchecked(moto_rt::num_cpus()) }) | |
| } | |
| pub fn yield_now() { | |
| moto_rt::thread::yield_now() | |
| } | |
| pub fn sleep(dur: Duration) { | |
| moto_rt::thread::sleep_until(moto_rt::time::Instant::now() + dur) | |
| } | |
| pub fn sleep_until(deadline: Instant) { | |
| moto_rt::thread::sleep_until(deadline.into_inner()) | |
| } |