]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
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 | //! A simple spin lock based thread parker. Used on platforms without better | |
9 | //! parking facilities available. | |
10 | ||
11 | use core::sync::atomic::{spin_loop_hint, AtomicBool, Ordering}; | |
f035d41b XL |
12 | use instant::Instant; |
13 | use std::thread; | |
ba9703b0 XL |
14 | |
15 | // Helper type for putting a thread to sleep until some other thread wakes it up | |
16 | pub struct ThreadParker { | |
17 | parked: AtomicBool, | |
18 | } | |
19 | ||
20 | impl super::ThreadParkerT for ThreadParker { | |
21 | type UnparkHandle = UnparkHandle; | |
22 | ||
23 | const IS_CHEAP_TO_CONSTRUCT: bool = true; | |
24 | ||
25 | #[inline] | |
26 | fn new() -> ThreadParker { | |
27 | ThreadParker { | |
28 | parked: AtomicBool::new(false), | |
29 | } | |
30 | } | |
31 | ||
32 | #[inline] | |
33 | unsafe fn prepare_park(&self) { | |
34 | self.parked.store(true, Ordering::Relaxed); | |
35 | } | |
36 | ||
37 | #[inline] | |
38 | unsafe fn timed_out(&self) -> bool { | |
39 | self.parked.load(Ordering::Relaxed) != false | |
40 | } | |
41 | ||
42 | #[inline] | |
43 | unsafe fn park(&self) { | |
44 | while self.parked.load(Ordering::Acquire) != false { | |
45 | spin_loop_hint(); | |
46 | } | |
47 | } | |
48 | ||
49 | #[inline] | |
50 | unsafe fn park_until(&self, timeout: Instant) -> bool { | |
51 | while self.parked.load(Ordering::Acquire) != false { | |
52 | if Instant::now() >= timeout { | |
53 | return false; | |
54 | } | |
55 | spin_loop_hint(); | |
56 | } | |
57 | true | |
58 | } | |
59 | ||
60 | #[inline] | |
61 | unsafe fn unpark_lock(&self) -> UnparkHandle { | |
62 | // We don't need to lock anything, just clear the state | |
63 | self.parked.store(false, Ordering::Release); | |
64 | UnparkHandle(()) | |
65 | } | |
66 | } | |
67 | ||
68 | pub struct UnparkHandle(()); | |
69 | ||
70 | impl super::UnparkHandleT for UnparkHandle { | |
71 | #[inline] | |
72 | unsafe fn unpark(self) {} | |
73 | } | |
74 | ||
75 | #[inline] | |
76 | pub fn thread_yield() { | |
77 | thread::yield_now(); | |
78 | } |