1 | //! Miscellaneous tools for concurrent programming. |
2 | //! |
3 | //! ## Atomics |
4 | //! |
5 | //! * [`AtomicCell`], a thread-safe mutable memory location. |
6 | //! * [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering. |
7 | //! |
8 | //! ## Thread synchronization |
9 | //! |
10 | //! * [`Parker`], a thread parking primitive. |
11 | //! * [`ShardedLock`], a sharded reader-writer lock with fast concurrent reads. |
12 | //! * [`WaitGroup`], for synchronizing the beginning or end of some computation. |
13 | //! |
14 | //! ## Utilities |
15 | //! |
16 | //! * [`Backoff`], for exponential backoff in spin loops. |
17 | //! * [`CachePadded`], for padding and aligning a value to the length of a cache line. |
18 | //! * [`scope`], for spawning threads that borrow local variables from the stack. |
19 | //! |
20 | //! [`AtomicCell`]: atomic::AtomicCell |
21 | //! [`AtomicConsume`]: atomic::AtomicConsume |
22 | //! [`Parker`]: sync::Parker |
23 | //! [`ShardedLock`]: sync::ShardedLock |
24 | //! [`WaitGroup`]: sync::WaitGroup |
25 | //! [`scope`]: thread::scope |
26 | |
27 | #![doc (test( |
28 | no_crate_inject, |
29 | attr( |
30 | deny(warnings, rust_2018_idioms), |
31 | allow(dead_code, unused_assignments, unused_variables) |
32 | ) |
33 | ))] |
34 | #![warn ( |
35 | missing_docs, |
36 | missing_debug_implementations, |
37 | rust_2018_idioms, |
38 | unreachable_pub |
39 | )] |
40 | #![cfg_attr (not(feature = "std" ), no_std)] |
41 | |
42 | #[cfg (crossbeam_loom)] |
43 | #[allow (unused_imports)] |
44 | mod primitive { |
45 | pub(crate) mod sync { |
46 | pub(crate) mod atomic { |
47 | pub(crate) use loom::sync::atomic::spin_loop_hint; |
48 | pub(crate) use loom::sync::atomic::{ |
49 | AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, |
50 | AtomicU32, AtomicU64, AtomicU8, AtomicUsize, |
51 | }; |
52 | |
53 | // FIXME: loom does not support compiler_fence at the moment. |
54 | // https://github.com/tokio-rs/loom/issues/117 |
55 | // we use fence as a stand-in for compiler_fence for the time being. |
56 | // this may miss some races since fence is stronger than compiler_fence, |
57 | // but it's the best we can do for the time being. |
58 | pub(crate) use loom::sync::atomic::fence as compiler_fence; |
59 | } |
60 | pub(crate) use loom::sync::{Arc, Condvar, Mutex}; |
61 | } |
62 | } |
63 | #[cfg (not(crossbeam_loom))] |
64 | #[allow (unused_imports)] |
65 | mod primitive { |
66 | pub(crate) mod sync { |
67 | pub(crate) mod atomic { |
68 | pub(crate) use core::sync::atomic::compiler_fence; |
69 | // TODO(taiki-e): once we bump the minimum required Rust version to 1.49+, |
70 | // use [`core::hint::spin_loop`] instead. |
71 | #[allow (deprecated)] |
72 | pub(crate) use core::sync::atomic::spin_loop_hint; |
73 | #[cfg (not(crossbeam_no_atomic))] |
74 | pub(crate) use core::sync::atomic::{ |
75 | AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, |
76 | AtomicU8, AtomicUsize, |
77 | }; |
78 | #[cfg (not(crossbeam_no_atomic_64))] |
79 | pub(crate) use core::sync::atomic::{AtomicI64, AtomicU64}; |
80 | } |
81 | |
82 | #[cfg (feature = "std" )] |
83 | pub(crate) use std::sync::{Arc, Condvar, Mutex}; |
84 | } |
85 | } |
86 | |
87 | pub mod atomic; |
88 | |
89 | mod cache_padded; |
90 | pub use crate::cache_padded::CachePadded; |
91 | |
92 | mod backoff; |
93 | pub use crate::backoff::Backoff; |
94 | |
95 | use cfg_if::cfg_if; |
96 | |
97 | cfg_if! { |
98 | if #[cfg(feature = "std" )] { |
99 | pub mod sync; |
100 | |
101 | #[cfg (not(crossbeam_loom))] |
102 | pub mod thread; |
103 | } |
104 | } |
105 | |