This commit applies rustfmt with rust-lang/rust's default settings to files in src/libstd/sys *that are not involved in any currently open PR* to minimize merge conflicts. THe list of files involved in open PRs was determined by querying GitHub's GraphQL API with this script: https://gist.github.com/dtolnay/aa9c34993dc051a4f344d1b10e4487e8 With the list of files from the script in outstanding_files, the relevant commands were: $ find src/libstd/sys -name '*.rs' \ | xargs rustfmt --edition=2018 --unstable-features --skip-children $ rg libstd/sys outstanding_files | xargs git checkout -- Repeating this process several months apart should get us coverage of most of the rest of the files. To confirm no funny business: $ git checkout $THIS_COMMIT^ $ git show --pretty= --name-only $THIS_COMMIT \ | xargs rustfmt --edition=2018 --unstable-features --skip-children $ git diff $THIS_COMMIT # there should be no difference
93 lines
2.6 KiB
Rust
93 lines
2.6 KiB
Rust
#![cfg_attr(test, allow(dead_code))] // why is this necessary?
|
|
use crate::ffi::CStr;
|
|
use crate::io;
|
|
use crate::time::Duration;
|
|
|
|
use super::abi::usercalls;
|
|
|
|
pub struct Thread(task_queue::JoinHandle);
|
|
|
|
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
|
|
|
mod task_queue {
|
|
use crate::sync::mpsc;
|
|
use crate::sync::{Mutex, MutexGuard, Once};
|
|
|
|
pub type JoinHandle = mpsc::Receiver<()>;
|
|
|
|
pub(super) struct Task {
|
|
p: Box<dyn FnOnce()>,
|
|
done: mpsc::Sender<()>,
|
|
}
|
|
|
|
impl Task {
|
|
pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
|
|
let (done, recv) = mpsc::channel();
|
|
(Task { p, done }, recv)
|
|
}
|
|
|
|
pub(super) fn run(self) {
|
|
(self.p)();
|
|
let _ = self.done.send(());
|
|
}
|
|
}
|
|
|
|
#[cfg_attr(test, linkage = "available_externally")]
|
|
#[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"]
|
|
static TASK_QUEUE_INIT: Once = Once::new();
|
|
#[cfg_attr(test, linkage = "available_externally")]
|
|
#[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
|
|
static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
|
|
|
|
pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
|
|
unsafe {
|
|
TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()));
|
|
TASK_QUEUE.as_ref().unwrap().lock().unwrap()
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Thread {
|
|
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
|
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
|
let mut queue_lock = task_queue::lock();
|
|
usercalls::launch_thread()?;
|
|
let (task, handle) = task_queue::Task::new(p);
|
|
queue_lock.push(task);
|
|
Ok(Thread(handle))
|
|
}
|
|
|
|
pub(super) fn entry() {
|
|
let mut pending_tasks = task_queue::lock();
|
|
let task = rtunwrap!(Some, pending_tasks.pop());
|
|
drop(pending_tasks); // make sure to not hold the task queue lock longer than necessary
|
|
task.run()
|
|
}
|
|
|
|
pub fn yield_now() {
|
|
let wait_error = rtunwrap!(Err, usercalls::wait(0, usercalls::raw::WAIT_NO));
|
|
rtassert!(wait_error.kind() == io::ErrorKind::WouldBlock);
|
|
}
|
|
|
|
pub fn set_name(_name: &CStr) {
|
|
// FIXME: could store this pointer in TLS somewhere
|
|
}
|
|
|
|
pub fn sleep(_dur: Duration) {
|
|
rtabort!("can't sleep"); // FIXME
|
|
}
|
|
|
|
pub fn join(self) {
|
|
let _ = self.0.recv();
|
|
}
|
|
}
|
|
|
|
pub mod guard {
|
|
pub type Guard = !;
|
|
pub unsafe fn current() -> Option<Guard> {
|
|
None
|
|
}
|
|
pub unsafe fn init() -> Option<Guard> {
|
|
None
|
|
}
|
|
}
|