| 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 | |