1 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
4 use crate::time::Duration;
6 use super::abi::usercalls;
8 pub struct Thread(task_queue::JoinHandle);
10 pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
13 use crate::sync::mpsc;
14 use crate::sync::{Mutex, MutexGuard, Once};
16 pub type JoinHandle = mpsc::Receiver<()>;
18 pub(super) struct Task {
20 done: mpsc::Sender<()>,
24 pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
25 let (done, recv) = mpsc::channel();
26 (Task { p, done }, recv)
29 pub(super) fn run(self) {
31 let _ = self.done.send(());
35 #[cfg_attr(test, linkage = "available_externally")]
36 #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"]
37 static TASK_QUEUE_INIT: Once = Once::new();
38 #[cfg_attr(test, linkage = "available_externally")]
39 #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
40 static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
42 pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
44 TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()));
45 TASK_QUEUE.as_ref().unwrap().lock().unwrap()
51 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
52 pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
53 let mut queue_lock = task_queue::lock();
54 unsafe { usercalls::launch_thread()? };
55 let (task, handle) = task_queue::Task::new(p);
56 queue_lock.push(task);
60 pub(super) fn entry() {
61 let mut pending_tasks = task_queue::lock();
62 let task = rtunwrap!(Some, pending_tasks.pop());
63 drop(pending_tasks); // make sure to not hold the task queue lock longer than necessary
68 let wait_error = rtunwrap!(Err, usercalls::wait(0, usercalls::raw::WAIT_NO));
69 rtassert!(wait_error.kind() == io::ErrorKind::WouldBlock);
72 pub fn set_name(_name: &CStr) {
73 // FIXME: could store this pointer in TLS somewhere
76 pub fn sleep(dur: Duration) {
77 usercalls::wait_timeout(0, dur, || true);
81 let _ = self.0.recv();
87 pub unsafe fn current() -> Option<Guard> {
90 pub unsafe fn init() -> Option<Guard> {