]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/sgx/thread.rs
Improve some compiletest documentation
[rust.git] / src / libstd / sys / sgx / thread.rs
1 use crate::boxed::FnBox;
2 use crate::ffi::CStr;
3 use crate::io;
4 use crate::time::Duration;
5
6 use super::abi::usercalls;
7
8 pub struct Thread(task_queue::JoinHandle);
9
10 pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
11
12 mod task_queue {
13     use crate::sync::{Mutex, MutexGuard, Once};
14     use crate::sync::mpsc;
15     use crate::boxed::FnBox;
16
17     pub type JoinHandle = mpsc::Receiver<()>;
18
19     pub(super) struct Task {
20         p: Box<dyn FnBox()>,
21         done: mpsc::Sender<()>,
22     }
23
24     impl Task {
25         pub(super) fn new(p: Box<dyn FnBox()>) -> (Task, JoinHandle) {
26             let (done, recv) = mpsc::channel();
27             (Task { p, done }, recv)
28         }
29
30         pub(super) fn run(self) {
31             (self.p)();
32             let _ = self.done.send(());
33         }
34     }
35
36     static TASK_QUEUE_INIT: Once = Once::new();
37     static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
38
39     pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
40         unsafe {
41             TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()) );
42             TASK_QUEUE.as_ref().unwrap().lock().unwrap()
43         }
44     }
45 }
46
47 impl Thread {
48     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
49     pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>)
50         -> io::Result<Thread>
51     {
52         let mut queue_lock = task_queue::lock();
53         usercalls::launch_thread()?;
54         let (task, handle) = task_queue::Task::new(p);
55         queue_lock.push(task);
56         Ok(Thread(handle))
57     }
58
59     pub(super) fn entry() {
60         let mut guard = task_queue::lock();
61         let task = guard.pop().expect("Thread started but no tasks pending");
62         drop(guard); // make sure to not hold the task queue lock longer than necessary
63         task.run()
64     }
65
66     pub fn yield_now() {
67         assert_eq!(
68             usercalls::wait(0, usercalls::raw::WAIT_NO).unwrap_err().kind(),
69             io::ErrorKind::WouldBlock
70         );
71     }
72
73     pub fn set_name(_name: &CStr) {
74         // FIXME: could store this pointer in TLS somewhere
75     }
76
77     pub fn sleep(_dur: Duration) {
78         panic!("can't sleep"); // FIXME
79     }
80
81     pub fn join(self) {
82         let _ = self.0.recv();
83     }
84 }
85
86 pub mod guard {
87     pub type Guard = !;
88     pub unsafe fn current() -> Option<Guard> { None }
89     pub unsafe fn init() -> Option<Guard> { None }
90 }