1 #![allow(dead_code)] 2 3 use crate::std::ffi::CStr; 4 use crate::std::io; 5 use crate::std::mem; 6 use crate::std::num::NonZeroUsize; 7 use crate::std::ptr; 8 use crate::std::sys::hermit::abi; 9 use crate::std::sys::hermit::thread_local_dtor::run_dtors; 10 use crate::std::time::Duration; 11 12 pub type Tid = abi::Tid; 13 14 pub struct Thread { 15 tid: Tid, 16 } 17 18 unsafe impl Send for Thread {} 19 unsafe impl Sync for Thread {} 20 21 pub const DEFAULT_MIN_STACK_SIZE: usize = 1 << 20; 22 23 impl Thread { 24 pub unsafe fn new_with_coreid( 25 stack: usize, 26 p: Box<dyn FnOnce()>, 27 core_id: isize, 28 ) -> io::Result<Thread> { 29 let p = Box::into_raw(Box::new(p)); 30 let tid = abi::spawn2( 31 thread_start, 32 p.expose_addr(), 33 abi::Priority::into(abi::NORMAL_PRIO), 34 stack, 35 core_id, 36 ); 37 38 return if tid == 0 { 39 // The thread failed to start and as a result p was not consumed. Therefore, it is 40 // safe to reconstruct the box so that it gets deallocated. 41 drop(Box::from_raw(p)); 42 Err(io::const_io_error!( 43 io::ErrorKind::Uncategorized, 44 "Unable to create thread!" 45 )) 46 } else { 47 Ok(Thread { tid: tid }) 48 }; 49 50 extern "C" fn thread_start(main: usize) { 51 unsafe { 52 // Finally, let's run some code. 53 Box::from_raw(ptr::from_exposed_addr::<Box<dyn FnOnce()>>(main).cast_mut())(); 54 55 // run all destructors 56 run_dtors(); 57 } 58 } 59 } 60 61 pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> { 62 Thread::new_with_coreid(stack, p, -1 /* = no specific core */) 63 } 64 65 #[inline] 66 pub fn yield_now() { 67 unsafe { 68 abi::yield_now(); 69 } 70 } 71 72 #[inline] 73 pub fn set_name(_name: &CStr) { 74 // nope 75 } 76 77 #[inline] 78 pub fn sleep(dur: Duration) { 79 unsafe { 80 abi::usleep(dur.as_micros() as u64); 81 } 82 } 83 84 pub fn join(self) { 85 unsafe { 86 let _ = abi::join(self.tid); 87 } 88 } 89 90 #[inline] 91 pub fn id(&self) -> Tid { 92 self.tid 93 } 94 95 #[inline] 96 pub fn into_id(self) -> Tid { 97 let id = self.tid; 98 mem::forget(self); 99 id 100 } 101 } 102 103 pub fn available_parallelism() -> io::Result<NonZeroUsize> { 104 unsafe { Ok(NonZeroUsize::new_unchecked(abi::get_processor_count())) } 105 } 106 107 pub mod guard { 108 pub type Guard = !; 109 pub unsafe fn current() -> Option<Guard> { 110 None 111 } 112 pub unsafe fn init() -> Option<Guard> { 113 None 114 } 115 } 116