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