1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
16 use super::abi::usercalls;
18 pub struct Thread(task_queue::JoinHandle);
20 pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
23 use sync::{Mutex, MutexGuard, Once};
27 pub type JoinHandle = mpsc::Receiver<()>;
29 pub(super) struct Task {
31 done: mpsc::Sender<()>,
35 pub(super) fn new(p: Box<dyn FnBox()>) -> (Task, JoinHandle) {
36 let (done, recv) = mpsc::channel();
37 (Task { p, done }, recv)
40 pub(super) fn run(self) {
42 let _ = self.done.send(());
46 static TASK_QUEUE_INIT: Once = Once::new();
47 static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
49 pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
51 TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()) );
52 TASK_QUEUE.as_ref().unwrap().lock().unwrap()
58 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
59 pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>)
62 let mut queue_lock = task_queue::lock();
63 usercalls::launch_thread()?;
64 let (task, handle) = task_queue::Task::new(p);
65 queue_lock.push(task);
69 pub(super) fn entry() {
70 let mut guard = task_queue::lock();
71 let task = guard.pop().expect("Thread started but no tasks pending");
72 drop(guard); // make sure to not hold the task queue lock longer than necessary
78 usercalls::wait(0, usercalls::WAIT_NO).unwrap_err().kind(),
79 io::ErrorKind::WouldBlock
83 pub fn set_name(_name: &CStr) {
84 // FIXME: could store this pointer in TLS somewhere
87 pub fn sleep(_dur: Duration) {
88 panic!("can't sleep"); // FIXME
92 let _ = self.0.recv();
98 pub unsafe fn current() -> Option<Guard> { None }
99 pub unsafe fn init() -> Option<Guard> { None }