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 //! A simple spin lock based thread parker. Used on platforms without better
9 //! parking facilities available.
11 use core
::sync
::atomic
::{spin_loop_hint, AtomicBool, Ordering}
;
12 use std
::{thread, time::Instant}
;
14 // Helper type for putting a thread to sleep until some other thread wakes it up
15 pub struct ThreadParker
{
19 impl super::ThreadParkerT
for ThreadParker
{
20 type UnparkHandle
= UnparkHandle
;
22 const IS_CHEAP_TO_CONSTRUCT
: bool
= true;
25 fn new() -> ThreadParker
{
27 parked
: AtomicBool
::new(false),
32 unsafe fn prepare_park(&self) {
33 self.parked
.store(true, Ordering
::Relaxed
);
37 unsafe fn timed_out(&self) -> bool
{
38 self.parked
.load(Ordering
::Relaxed
) != false
42 unsafe fn park(&self) {
43 while self.parked
.load(Ordering
::Acquire
) != false {
49 unsafe fn park_until(&self, timeout
: Instant
) -> bool
{
50 while self.parked
.load(Ordering
::Acquire
) != false {
51 if Instant
::now() >= timeout
{
60 unsafe fn unpark_lock(&self) -> UnparkHandle
{
61 // We don't need to lock anything, just clear the state
62 self.parked
.store(false, Ordering
::Release
);
67 pub struct UnparkHandle(());
69 impl super::UnparkHandleT
for UnparkHandle
{
71 unsafe fn unpark(self) {}
75 pub fn thread_yield() {