xref: /linux/rust/kernel/sync/atomic/ordering.rs (revision 88b489385bfe3713497a63c0dcf4dd7852cf4568)
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