1 use crate::boxed::FnBox;
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::{Mutex, MutexGuard, Once};
14 use crate::sync::mpsc;
15 use crate::boxed::FnBox;
17 pub type JoinHandle = mpsc::Receiver<()>;
19 pub(super) struct Task {
21 done: mpsc::Sender<()>,
25 pub(super) fn new(p: Box<dyn FnBox()>) -> (Task, JoinHandle) {
26 let (done, recv) = mpsc::channel();
27 (Task { p, done }, recv)
30 pub(super) fn run(self) {
32 let _ = self.done.send(());
36 static TASK_QUEUE_INIT: Once = Once::new();
37 static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
39 pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
41 TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()) );
42 TASK_QUEUE.as_ref().unwrap().lock().unwrap()
48 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
49 pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>)
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);
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
68 usercalls::wait(0, usercalls::raw::WAIT_NO).unwrap_err().kind(),
69 io::ErrorKind::WouldBlock
73 pub fn set_name(_name: &CStr) {
74 // FIXME: could store this pointer in TLS somewhere
77 pub fn sleep(_dur: Duration) {
78 panic!("can't sleep"); // FIXME
82 let _ = self.0.recv();
88 pub unsafe fn current() -> Option<Guard> { None }
89 pub unsafe fn init() -> Option<Guard> { None }