summaryrefslogtreecommitdiff
path: root/rust/kernel/sync/atomic/ordering.rs
blob: 3f103aa8db99b18fc9f8899b3bc3bbe1967c19ca (plain)
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// 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 {}