]>
Commit | Line | Data |
---|---|---|
532ac7d7 XL |
1 | use crate::boxed::FnBox; |
2 | use crate::ffi::CStr; | |
3 | use crate::io; | |
4 | use crate::mem; | |
5 | use crate::sys_common::thread::start_thread; | |
6 | use crate::sys::{cvt, syscall}; | |
7 | use crate::time::Duration; | |
476ff2be | 8 | |
ea8adc8c XL |
9 | pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; |
10 | ||
476ff2be SL |
11 | pub struct Thread { |
12 | id: usize, | |
13 | } | |
14 | ||
15 | // Some platforms may have pthread_t as a pointer in which case we still want | |
16 | // a thread to be Send/Sync | |
17 | unsafe impl Send for Thread {} | |
18 | unsafe impl Sync for Thread {} | |
19 | ||
20 | impl Thread { | |
0731742a XL |
21 | // unsafe: see thread::Builder::spawn_unchecked for safety requirements |
22 | pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> { | |
476ff2be SL |
23 | let p = box p; |
24 | ||
25 | let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?; | |
26 | if id == 0 { | |
27 | start_thread(&*p as *const _ as *mut _); | |
28 | let _ = syscall::exit(0); | |
29 | panic!("thread failed to exit"); | |
30 | } else { | |
31 | mem::forget(p); | |
a1dfa0c6 | 32 | Ok(Thread { id }) |
476ff2be SL |
33 | } |
34 | } | |
35 | ||
36 | pub fn yield_now() { | |
37 | let ret = syscall::sched_yield().expect("failed to sched_yield"); | |
38 | debug_assert_eq!(ret, 0); | |
39 | } | |
40 | ||
41 | pub fn set_name(_name: &CStr) { | |
42 | ||
43 | } | |
44 | ||
45 | pub fn sleep(dur: Duration) { | |
46 | let mut secs = dur.as_secs(); | |
47 | let mut nsecs = dur.subsec_nanos() as i32; | |
48 | ||
49 | // If we're awoken with a signal then the return value will be -1 and | |
50 | // nanosleep will fill in `ts` with the remaining time. | |
51 | while secs > 0 || nsecs > 0 { | |
52 | let req = syscall::TimeSpec { | |
53 | tv_sec: secs as i64, | |
54 | tv_nsec: nsecs, | |
55 | }; | |
56 | secs -= req.tv_sec as u64; | |
57 | let mut rem = syscall::TimeSpec::default(); | |
58 | if syscall::nanosleep(&req, &mut rem).is_err() { | |
59 | secs += rem.tv_sec as u64; | |
60 | nsecs = rem.tv_nsec; | |
61 | } else { | |
62 | nsecs = 0; | |
63 | } | |
64 | } | |
65 | } | |
66 | ||
67 | pub fn join(self) { | |
68 | let mut status = 0; | |
69 | syscall::waitpid(self.id, &mut status, 0).unwrap(); | |
70 | } | |
71 | ||
72 | pub fn id(&self) -> usize { self.id } | |
73 | ||
74 | pub fn into_id(self) -> usize { | |
75 | let id = self.id; | |
76 | mem::forget(self); | |
77 | id | |
78 | } | |
79 | } | |
80 | ||
81 | pub mod guard { | |
2c00a5a8 XL |
82 | pub type Guard = !; |
83 | pub unsafe fn current() -> Option<Guard> { None } | |
84 | pub unsafe fn init() -> Option<Guard> { None } | |
476ff2be | 85 | } |