1use crate::boxed::Box;
4use crate::io;
5use core::mem::forget;
6use core::num::NonZeroUsize;
7use core::ptr::{null_mut, NonNull};
8
9#[allow(dead_code)] pub struct ThreadId(usize);
13
14pub struct Thread(origin::thread::Thread);
15
16impl Thread {
17 pub fn id(&self) -> ThreadId {
18 ThreadId(self.0.to_raw().addr())
19 }
20}
21
22pub struct JoinHandle(Thread);
23
24impl JoinHandle {
25 pub fn join(self) -> io::Result<()> {
26 unsafe {
27 origin::thread::join(self.0 .0);
28 }
29
30 forget(self);
32
33 Ok(())
34 }
35}
36
37impl Drop for JoinHandle {
38 fn drop(&mut self) {
39 unsafe {
40 origin::thread::detach(self.0 .0);
41 }
42 }
43}
44
45pub fn spawn<F>(f: F) -> JoinHandle
46where
47 F: FnOnce() + Send + 'static,
48{
49 let boxed: Box<dyn FnOnce() + Send + 'static> = Box::new(move || {
51 #[cfg(feature = "stack-overflow")]
52 let _handler = unsafe { crate::stack_overflow::Handler::new() };
53
54 f()
55 });
56
57 let boxed = Box::new(boxed);
69 let raw: *mut Box<dyn FnOnce() + Send + 'static> = Box::into_raw(boxed);
70 let args = [NonNull::new(raw.cast())];
71
72 let thread = unsafe {
73 let r = origin::thread::create(
74 move |args| {
75 let raw: *mut Box<dyn FnOnce() + Send + 'static> = match args[0] {
84 Some(raw) => raw.as_ptr().cast(),
85 None => null_mut(),
86 };
87 let boxed: Box<Box<dyn FnOnce() + Send + 'static>> = Box::from_raw(raw);
88 (*boxed)();
89
90 None
91 },
92 &args,
93 origin::thread::default_stack_size(),
94 origin::thread::default_guard_size(),
95 );
96 r.unwrap()
97 };
98
99 JoinHandle(Thread(thread))
100}
101
102pub fn current() -> Thread {
103 Thread(origin::thread::current())
104}
105
106pub(crate) struct GetThreadId;
107
108unsafe impl rustix_futex_sync::lock_api::GetThreadId for GetThreadId {
109 const INIT: Self = Self;
110
111 fn nonzero_thread_id(&self) -> NonZeroUsize {
112 origin::thread::current().to_raw_non_null().addr()
113 }
114}
115
116pub(crate) type ReentrantMutex<T> = rustix_futex_sync::ReentrantMutex<GetThreadId, T>;
117pub(crate) type ReentrantMutexGuard<'a, T> =
118 rustix_futex_sync::ReentrantMutexGuard<'a, GetThreadId, T>;