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