1*b638c9bcSBoqun Feng // SPDX-License-Identifier: GPL-2.0 2*b638c9bcSBoqun Feng 3*b638c9bcSBoqun Feng //! Memory orderings. 4*b638c9bcSBoqun Feng //! 5*b638c9bcSBoqun Feng //! The semantics of these orderings follows the [`LKMM`] definitions and rules. 6*b638c9bcSBoqun Feng //! 7*b638c9bcSBoqun Feng //! - [`Acquire`] provides ordering between the load part of the annotated operation and all the 8*b638c9bcSBoqun Feng //! following memory accesses, and if there is a store part, the store part has the [`Relaxed`] 9*b638c9bcSBoqun Feng //! ordering. 10*b638c9bcSBoqun Feng //! - [`Release`] provides ordering between all the preceding memory accesses and the store part of 11*b638c9bcSBoqun Feng //! the annotated operation, and if there is a load part, the load part has the [`Relaxed`] 12*b638c9bcSBoqun Feng //! ordering. 13*b638c9bcSBoqun Feng //! - [`Full`] means "fully-ordered", that is: 14*b638c9bcSBoqun Feng //! - It provides ordering between all the preceding memory accesses and the annotated operation. 15*b638c9bcSBoqun Feng //! - It provides ordering between the annotated operation and all the following memory accesses. 16*b638c9bcSBoqun Feng //! - It provides ordering between all the preceding memory accesses and all the following memory 17*b638c9bcSBoqun Feng //! accesses. 18*b638c9bcSBoqun Feng //! - All the orderings are the same strength as a full memory barrier (i.e. `smp_mb()`). 19*b638c9bcSBoqun Feng //! - [`Relaxed`] provides no ordering except the dependency orderings. Dependency orderings are 20*b638c9bcSBoqun Feng //! described in "DEPENDENCY RELATIONS" in [`LKMM`]'s [`explanation`]. 21*b638c9bcSBoqun Feng //! 22*b638c9bcSBoqun Feng //! [`LKMM`]: srctree/tools/memory-model/ 23*b638c9bcSBoqun Feng //! [`explanation`]: srctree/tools/memory-model/Documentation/explanation.txt 24*b638c9bcSBoqun Feng 25*b638c9bcSBoqun Feng /// The annotation type for relaxed memory ordering, for the description of relaxed memory 26*b638c9bcSBoqun Feng /// ordering, see [module-level documentation]. 27*b638c9bcSBoqun Feng /// 28*b638c9bcSBoqun Feng /// [module-level documentation]: crate::sync::atomic::ordering 29*b638c9bcSBoqun Feng pub struct Relaxed; 30*b638c9bcSBoqun Feng 31*b638c9bcSBoqun Feng /// The annotation type for acquire memory ordering, for the description of acquire memory 32*b638c9bcSBoqun Feng /// ordering, see [module-level documentation]. 33*b638c9bcSBoqun Feng /// 34*b638c9bcSBoqun Feng /// [module-level documentation]: crate::sync::atomic::ordering 35*b638c9bcSBoqun Feng pub struct Acquire; 36*b638c9bcSBoqun Feng 37*b638c9bcSBoqun Feng /// The annotation type for release memory ordering, for the description of release memory 38*b638c9bcSBoqun Feng /// ordering, see [module-level documentation]. 39*b638c9bcSBoqun Feng /// 40*b638c9bcSBoqun Feng /// [module-level documentation]: crate::sync::atomic::ordering 41*b638c9bcSBoqun Feng pub struct Release; 42*b638c9bcSBoqun Feng 43*b638c9bcSBoqun Feng /// The annotation type for fully-ordered memory ordering, for the description fully-ordered memory 44*b638c9bcSBoqun Feng /// ordering, see [module-level documentation]. 45*b638c9bcSBoqun Feng /// 46*b638c9bcSBoqun Feng /// [module-level documentation]: crate::sync::atomic::ordering 47*b638c9bcSBoqun Feng pub struct Full; 48*b638c9bcSBoqun Feng 49*b638c9bcSBoqun Feng /// Describes the exact memory ordering. 50*b638c9bcSBoqun Feng #[doc(hidden)] 51*b638c9bcSBoqun Feng pub enum OrderingType { 52*b638c9bcSBoqun Feng /// Relaxed ordering. 53*b638c9bcSBoqun Feng Relaxed, 54*b638c9bcSBoqun Feng /// Acquire ordering. 55*b638c9bcSBoqun Feng Acquire, 56*b638c9bcSBoqun Feng /// Release ordering. 57*b638c9bcSBoqun Feng Release, 58*b638c9bcSBoqun Feng /// Fully-ordered. 59*b638c9bcSBoqun Feng Full, 60*b638c9bcSBoqun Feng } 61*b638c9bcSBoqun Feng 62*b638c9bcSBoqun Feng mod internal { 63*b638c9bcSBoqun Feng /// Sealed trait, can be only implemented inside atomic mod. 64*b638c9bcSBoqun Feng pub trait Sealed {} 65*b638c9bcSBoqun Feng 66*b638c9bcSBoqun Feng impl Sealed for super::Relaxed {} 67*b638c9bcSBoqun Feng impl Sealed for super::Acquire {} 68*b638c9bcSBoqun Feng impl Sealed for super::Release {} 69*b638c9bcSBoqun Feng impl Sealed for super::Full {} 70*b638c9bcSBoqun Feng } 71*b638c9bcSBoqun Feng 72*b638c9bcSBoqun Feng /// The trait bound for annotating operations that support any ordering. 73*b638c9bcSBoqun Feng pub trait Ordering: internal::Sealed { 74*b638c9bcSBoqun Feng /// Describes the exact memory ordering. 75*b638c9bcSBoqun Feng const TYPE: OrderingType; 76*b638c9bcSBoqun Feng } 77*b638c9bcSBoqun Feng 78*b638c9bcSBoqun Feng impl Ordering for Relaxed { 79*b638c9bcSBoqun Feng const TYPE: OrderingType = OrderingType::Relaxed; 80*b638c9bcSBoqun Feng } 81*b638c9bcSBoqun Feng 82*b638c9bcSBoqun Feng impl Ordering for Acquire { 83*b638c9bcSBoqun Feng const TYPE: OrderingType = OrderingType::Acquire; 84*b638c9bcSBoqun Feng } 85*b638c9bcSBoqun Feng 86*b638c9bcSBoqun Feng impl Ordering for Release { 87*b638c9bcSBoqun Feng const TYPE: OrderingType = OrderingType::Release; 88*b638c9bcSBoqun Feng } 89*b638c9bcSBoqun Feng 90*b638c9bcSBoqun Feng impl Ordering for Full { 91*b638c9bcSBoqun Feng const TYPE: OrderingType = OrderingType::Full; 92*b638c9bcSBoqun Feng } 93*b638c9bcSBoqun Feng 94*b638c9bcSBoqun Feng /// The trait bound for operations that only support acquire or relaxed ordering. 95*b638c9bcSBoqun Feng pub trait AcquireOrRelaxed: Ordering {} 96*b638c9bcSBoqun Feng 97*b638c9bcSBoqun Feng impl AcquireOrRelaxed for Acquire {} 98*b638c9bcSBoqun Feng impl AcquireOrRelaxed for Relaxed {} 99*b638c9bcSBoqun Feng 100*b638c9bcSBoqun Feng /// The trait bound for operations that only support release or relaxed ordering. 101*b638c9bcSBoqun Feng pub trait ReleaseOrRelaxed: Ordering {} 102*b638c9bcSBoqun Feng 103*b638c9bcSBoqun Feng impl ReleaseOrRelaxed for Release {} 104*b638c9bcSBoqun Feng impl ReleaseOrRelaxed for Relaxed {} 105