1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
//! Synchronized one-time and lazy initialization primitives that use spin-locks //! in case of concurrent accesses under contention. use core::sync::atomic::spin_loop_hint; use crate::cell::Block; use crate::internal::Internal; use crate::state::{AtomicOnceState, OnceState::WouldBlock, Waiter}; use crate::POISON_PANIC_MSG; /// A type for lazy initialization of e.g. global static variables, which /// provides the same functionality as the `lazy_static!` macro. /// /// This type uses spin-locks if the initialization is contended and is thus /// `#[no_std]` compatible. /// /// For the API of this type alias, see the API of the generic /// [`Lazy`](crate::raw::Lazy) type. pub type Lazy<T, F = fn() -> T> = crate::lazy::Lazy<T, Spin, F>; /// An interior mutability cell type which allows synchronized one-time /// initialization and read-only access exclusively after initialization. /// /// This type uses spin-locks if the initialization is contended and is thus /// `#[no_std]` compatible. /// /// For the API of this type alias, see the generic /// [`OnceCell`](crate::raw::OnceCell) type. pub type OnceCell<T> = crate::cell::OnceCell<T, Spin>; /// A synchronization primitive which can be used to run a one-time global /// initialization. /// /// This type uses spin-locks if the initialization is contended and is thus /// `#[no_std]` compatible. /// /// For the API of this type alias, see the generic /// [`OnceCell`](crate::raw::OnceCell) type. /// This is a specialization with `T = ()`. pub type Once = OnceCell<()>; //////////////////////////////////////////////////////////////////////////////////////////////////// // Spin //////////////////////////////////////////////////////////////////////////////////////////////////// /// Blocking strategy using spin-locks. #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] pub struct Spin; /********** impl Internal *************************************************************************/ impl Internal for Spin {} /********** impl Block ****************************************************************************/ impl Block for Spin { #[inline] fn block(state: &AtomicOnceState) { while let WouldBlock(_) = state.load().expect(POISON_PANIC_MSG) { spin_loop_hint() } } #[inline] fn unblock(_: Waiter) {} } #[cfg(test)] mod tests { generate_tests!(); }