1 // Copyright 2016 Amanieu d'Antras
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.
8 use core
::sync
::atomic
::{AtomicBool, Ordering}
;
12 thread
::current
as current_tcs
,
15 raw
::{Tcs, EV_UNPARK, WAIT_INDEFINITE}
,
22 // Helper type for putting a thread to sleep until some other thread wakes it up
23 pub struct ThreadParker
{
28 impl super::ThreadParkerT
for ThreadParker
{
29 type UnparkHandle
= UnparkHandle
;
31 const IS_CHEAP_TO_CONSTRUCT
: bool
= true;
34 fn new() -> ThreadParker
{
36 parked
: AtomicBool
::new(false),
42 unsafe fn prepare_park(&self) {
43 self.parked
.store(true, Ordering
::Relaxed
);
47 unsafe fn timed_out(&self) -> bool
{
48 self.parked
.load(Ordering
::Relaxed
)
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
);
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");
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
)
73 pub struct UnparkHandle(Tcs
);
75 impl super::UnparkHandleT
for UnparkHandle
{
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
);
92 pub fn thread_yield() {