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 hint { |
46 | pub(crate) use loom::hint::spin_loop; |
47 | } |
48 | pub(crate) mod sync { |
49 | pub(crate) mod atomic { |
50 | pub(crate) use loom::sync::atomic::{ |
51 | AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, |
52 | AtomicU32, AtomicU64, AtomicU8, AtomicUsize, Ordering, |
53 | }; |
54 | |
55 | // FIXME: loom does not support compiler_fence at the moment. |
56 | // https://github.com/tokio-rs/loom/issues/117 |
57 | // we use fence as a stand-in for compiler_fence for the time being. |
58 | // this may miss some races since fence is stronger than compiler_fence, |
59 | // but it's the best we can do for the time being. |
60 | pub(crate) use loom::sync::atomic::fence as compiler_fence; |
61 | } |
62 | pub(crate) use loom::sync::{Arc, Condvar, Mutex}; |
63 | } |
64 | } |
65 | #[cfg (not(crossbeam_loom))] |
66 | #[allow (unused_imports)] |
67 | mod primitive { |
68 | pub(crate) mod hint { |
69 | pub(crate) use core::hint::spin_loop; |
70 | } |
71 | pub(crate) mod sync { |
72 | pub(crate) mod atomic { |
73 | pub(crate) use core::sync::atomic::{compiler_fence, Ordering}; |
74 | #[cfg (not(crossbeam_no_atomic))] |
75 | pub(crate) use core::sync::atomic::{ |
76 | AtomicBool, AtomicI16, AtomicI8, AtomicIsize, AtomicU16, AtomicU8, AtomicUsize, |
77 | }; |
78 | #[cfg (not(crossbeam_no_atomic))] |
79 | #[cfg (any(target_has_atomic = "32" , not(target_pointer_width = "16" )))] |
80 | pub(crate) use core::sync::atomic::{AtomicI32, AtomicU32}; |
81 | #[cfg (not(crossbeam_no_atomic))] |
82 | #[cfg (any( |
83 | target_has_atomic = "64" , |
84 | not(any(target_pointer_width = "16" , target_pointer_width = "32" )), |
85 | ))] |
86 | pub(crate) use core::sync::atomic::{AtomicI64, AtomicU64}; |
87 | } |
88 | |
89 | #[cfg (feature = "std" )] |
90 | pub(crate) use std::sync::{Arc, Condvar, Mutex}; |
91 | } |
92 | } |
93 | |
94 | pub mod atomic; |
95 | |
96 | mod cache_padded; |
97 | pub use crate::cache_padded::CachePadded; |
98 | |
99 | mod backoff; |
100 | pub use crate::backoff::Backoff; |
101 | |
102 | use cfg_if::cfg_if; |
103 | |
104 | cfg_if! { |
105 | if #[cfg(feature = "std" )] { |
106 | pub mod sync; |
107 | |
108 | #[cfg (not(crossbeam_loom))] |
109 | pub mod thread; |
110 | } |
111 | } |
112 | |