| // SPDX-License-Identifier: GPL-2.0 |
| |
| //! Memory orderings. |
| //! |
| //! The semantics of these orderings follows the [`LKMM`] definitions and rules. |
| //! |
| //! - [`Acquire`] provides ordering between the load part of the annotated operation and all the |
| //! following memory accesses, and if there is a store part, the store part has the [`Relaxed`] |
| //! ordering. |
| //! - [`Release`] provides ordering between all the preceding memory accesses and the store part of |
| //! the annotated operation, and if there is a load part, the load part has the [`Relaxed`] |
| //! ordering. |
| //! - [`Full`] means "fully-ordered", that is: |
| //! - It provides ordering between all the preceding memory accesses and the annotated operation. |
| //! - It provides ordering between the annotated operation and all the following memory accesses. |
| //! - It provides ordering between all the preceding memory accesses and all the following memory |
| //! accesses. |
| //! - All the orderings are the same strength as a full memory barrier (i.e. `smp_mb()`). |
| //! - [`Relaxed`] provides no ordering except the dependency orderings. Dependency orderings are |
| //! described in "DEPENDENCY RELATIONS" in [`LKMM`]'s [`explanation`]. |
| //! |
| //! [`LKMM`]: srctree/tools/memory-model/ |
| //! [`explanation`]: srctree/tools/memory-model/Documentation/explanation.txt |
| |
| /// The annotation type for relaxed memory ordering, for the description of relaxed memory |
| /// ordering, see [module-level documentation]. |
| /// |
| /// [module-level documentation]: crate::sync::atomic::ordering |
| pub struct Relaxed; |
| |
| /// The annotation type for acquire memory ordering, for the description of acquire memory |
| /// ordering, see [module-level documentation]. |
| /// |
| /// [module-level documentation]: crate::sync::atomic::ordering |
| pub struct Acquire; |
| |
| /// The annotation type for release memory ordering, for the description of release memory |
| /// ordering, see [module-level documentation]. |
| /// |
| /// [module-level documentation]: crate::sync::atomic::ordering |
| pub struct Release; |
| |
| /// The annotation type for fully-ordered memory ordering, for the description fully-ordered memory |
| /// ordering, see [module-level documentation]. |
| /// |
| /// [module-level documentation]: crate::sync::atomic::ordering |
| pub struct Full; |
| |
| /// Describes the exact memory ordering. |
| #[doc(hidden)] |
| pub enum OrderingType { |
| /// Relaxed ordering. |
| Relaxed, |
| /// Acquire ordering. |
| Acquire, |
| /// Release ordering. |
| Release, |
| /// Fully-ordered. |
| Full, |
| } |
| |
| mod internal { |
| /// Sealed trait, can be only implemented inside atomic mod. |
| pub trait Sealed {} |
| |
| impl Sealed for super::Relaxed {} |
| impl Sealed for super::Acquire {} |
| impl Sealed for super::Release {} |
| impl Sealed for super::Full {} |
| } |
| |
| /// The trait bound for annotating operations that support any ordering. |
| pub trait Ordering: internal::Sealed { |
| /// Describes the exact memory ordering. |
| const TYPE: OrderingType; |
| } |
| |
| impl Ordering for Relaxed { |
| const TYPE: OrderingType = OrderingType::Relaxed; |
| } |
| |
| impl Ordering for Acquire { |
| const TYPE: OrderingType = OrderingType::Acquire; |
| } |
| |
| impl Ordering for Release { |
| const TYPE: OrderingType = OrderingType::Release; |
| } |
| |
| impl Ordering for Full { |
| const TYPE: OrderingType = OrderingType::Full; |
| } |
| |
| /// The trait bound for operations that only support acquire or relaxed ordering. |
| pub trait AcquireOrRelaxed: Ordering {} |
| |
| impl AcquireOrRelaxed for Acquire {} |
| impl AcquireOrRelaxed for Relaxed {} |
| |
| /// The trait bound for operations that only support release or relaxed ordering. |
| pub trait ReleaseOrRelaxed: Ordering {} |
| |
| impl ReleaseOrRelaxed for Release {} |
| impl ReleaseOrRelaxed for Relaxed {} |