]> git.proxmox.com Git - rustc.git/blob - vendor/parking_lot_core/src/thread_parker/sgx.rs
New upstream version 1.44.1+dfsg1
[rustc.git] / vendor / parking_lot_core / src / thread_parker / sgx.rs
1 // Copyright 2016 Amanieu d'Antras
2 //
3 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5 // http://opensource.org/licenses/MIT>, at your option. This file may not be
6 // copied, modified, or distributed except according to those terms.
7
8 use core::sync::atomic::{AtomicBool, Ordering};
9 use std::{
10 io,
11 os::fortanix_sgx::{
12 thread::current as current_tcs,
13 usercalls::{
14 self,
15 raw::{Tcs, EV_UNPARK, WAIT_INDEFINITE},
16 },
17 },
18 thread,
19 time::Instant,
20 };
21
22 // Helper type for putting a thread to sleep until some other thread wakes it up
23 pub struct ThreadParker {
24 parked: AtomicBool,
25 tcs: Tcs,
26 }
27
28 impl super::ThreadParkerT for ThreadParker {
29 type UnparkHandle = UnparkHandle;
30
31 const IS_CHEAP_TO_CONSTRUCT: bool = true;
32
33 #[inline]
34 fn new() -> ThreadParker {
35 ThreadParker {
36 parked: AtomicBool::new(false),
37 tcs: current_tcs(),
38 }
39 }
40
41 #[inline]
42 unsafe fn prepare_park(&self) {
43 self.parked.store(true, Ordering::Relaxed);
44 }
45
46 #[inline]
47 unsafe fn timed_out(&self) -> bool {
48 self.parked.load(Ordering::Relaxed)
49 }
50
51 #[inline]
52 unsafe fn park(&self) {
53 while self.parked.load(Ordering::Acquire) {
54 let result = usercalls::wait(EV_UNPARK, WAIT_INDEFINITE);
55 debug_assert_eq!(result.expect("wait returned error") & EV_UNPARK, EV_UNPARK);
56 }
57 }
58
59 #[inline]
60 unsafe fn park_until(&self, _timeout: Instant) -> bool {
61 // FIXME: https://github.com/fortanix/rust-sgx/issues/31
62 panic!("timeout not supported in SGX");
63 }
64
65 #[inline]
66 unsafe fn unpark_lock(&self) -> UnparkHandle {
67 // We don't need to lock anything, just clear the state
68 self.parked.store(false, Ordering::Release);
69 UnparkHandle(self.tcs)
70 }
71 }
72
73 pub struct UnparkHandle(Tcs);
74
75 impl super::UnparkHandleT for UnparkHandle {
76 #[inline]
77 unsafe fn unpark(self) {
78 let result = usercalls::send(EV_UNPARK, Some(self.0));
79 if cfg!(debug_assertions) {
80 if let Err(error) = result {
81 // `InvalidInput` may be returned if the thread we send to has
82 // already been unparked and exited.
83 if error.kind() != io::ErrorKind::InvalidInput {
84 panic!("send returned an unexpected error: {:?}", error);
85 }
86 }
87 }
88 }
89 }
90
91 #[inline]
92 pub fn thread_yield() {
93 thread::yield_now();
94 }