prism3_atomic/atomic/
traits.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9
10//! # Atomic Traits
11//!
12//! Defines common traits for atomic types, providing a unified interface
13//! for atomic operations.
14//!
15//! # Author
16//!
17//! Haixing Hu
18
19/// Common trait for all atomic types.
20///
21/// Provides basic atomic operations including load, store, swap,
22/// compare-and-set, and functional updates.
23///
24/// # Author
25///
26/// Haixing Hu
27pub trait Atomic {
28    /// The value type stored in the atomic.
29    type Value;
30
31    /// Loads the current value.
32    ///
33    /// Uses `Acquire` ordering by default.
34    ///
35    /// # Returns
36    ///
37    /// The current value.
38    fn load(&self) -> Self::Value;
39
40    /// Stores a new value.
41    ///
42    /// Uses `Release` ordering by default.
43    ///
44    /// # Parameters
45    ///
46    /// * `value` - The new value to store.
47    fn store(&self, value: Self::Value);
48
49    /// Swaps the current value with a new value, returning the old
50    /// value.
51    ///
52    /// Uses `AcqRel` ordering by default.
53    ///
54    /// # Parameters
55    ///
56    /// * `value` - The new value to swap in.
57    ///
58    /// # Returns
59    ///
60    /// The old value.
61    fn swap(&self, value: Self::Value) -> Self::Value;
62
63    /// Compares and sets the value atomically.
64    ///
65    /// If the current value equals `current`, sets it to `new` and
66    /// returns `Ok(())`. Otherwise, returns `Err(actual)` where
67    /// `actual` is the current value.
68    ///
69    /// Uses `AcqRel` ordering on success and `Acquire` ordering on
70    /// failure.
71    ///
72    /// # Parameters
73    ///
74    /// * `current` - The expected current value.
75    /// * `new` - The new value to set if current matches.
76    ///
77    /// # Returns
78    ///
79    /// `Ok(())` on success, or `Err(actual)` on failure where
80    /// `actual` is the real current value.
81    fn compare_set(&self, current: Self::Value, new: Self::Value) -> Result<(), Self::Value>;
82
83    /// Weak version of compare-and-set.
84    ///
85    /// May spuriously fail even when the comparison succeeds. Should
86    /// be used in a loop.
87    ///
88    /// Uses `AcqRel` ordering on success and `Acquire` ordering on
89    /// failure.
90    ///
91    /// # Parameters
92    ///
93    /// * `current` - The expected current value.
94    /// * `new` - The new value to set if current matches.
95    ///
96    /// # Returns
97    ///
98    /// `Ok(())` on success, or `Err(actual)` on failure.
99    fn compare_set_weak(&self, current: Self::Value, new: Self::Value) -> Result<(), Self::Value>;
100
101    /// Compares and exchanges the value atomically, returning the
102    /// previous value.
103    ///
104    /// If the current value equals `current`, sets it to `new` and
105    /// returns the old value. Otherwise, returns the actual current
106    /// value.
107    ///
108    /// This is similar to `compare_set` but always returns the actual
109    /// value instead of a Result, which can be more convenient in CAS
110    /// loops.
111    ///
112    /// Uses `AcqRel` ordering on success and `Acquire` ordering on
113    /// failure.
114    ///
115    /// # Parameters
116    ///
117    /// * `current` - The expected current value.
118    /// * `new` - The new value to set if current matches.
119    ///
120    /// # Returns
121    ///
122    /// The value before the operation. If it equals `current`, the
123    /// operation succeeded.
124    fn compare_exchange(&self, current: Self::Value, new: Self::Value) -> Self::Value;
125
126    /// Weak version of compare-and-exchange.
127    ///
128    /// May spuriously fail even when the comparison succeeds. Should
129    /// be used in a loop.
130    ///
131    /// Uses `AcqRel` ordering on success and `Acquire` ordering on
132    /// failure.
133    ///
134    /// # Parameters
135    ///
136    /// * `current` - The expected current value.
137    /// * `new` - The new value to set if current matches.
138    ///
139    /// # Returns
140    ///
141    /// The value before the operation.
142    fn compare_exchange_weak(&self, current: Self::Value, new: Self::Value) -> Self::Value;
143
144    /// Updates the value using a function, returning the old value.
145    ///
146    /// Internally uses a CAS loop until the update succeeds.
147    ///
148    /// # Parameters
149    ///
150    /// * `f` - A function that takes the current value and returns
151    ///   the new value.
152    ///
153    /// # Returns
154    ///
155    /// The old value before the update.
156    fn fetch_update<F>(&self, f: F) -> Self::Value
157    where
158        F: Fn(Self::Value) -> Self::Value;
159}
160
161/// Trait for atomic numeric types that support arithmetic operations.
162///
163/// Provides common arithmetic operations (add, subtract, multiply, divide)
164/// for both integer and floating-point atomic types. This trait unifies
165/// the arithmetic interface across all numeric atomic types.
166///
167/// # Note
168///
169/// Integer types also provide `fetch_inc()` and `fetch_dec()` methods
170/// as convenient shortcuts for incrementing/decrementing by 1, but these
171/// are not part of this trait as they are integer-specific operations.
172///
173/// # Author
174///
175/// Haixing Hu
176pub trait AtomicNumber: Atomic {
177    /// Adds a delta to the value, returning the old value.
178    ///
179    /// For integers, uses `Relaxed` ordering by default.
180    /// For floating-point types, uses `AcqRel` ordering (CAS loop).
181    ///
182    /// # Parameters
183    ///
184    /// * `delta` - The value to add.
185    ///
186    /// # Returns
187    ///
188    /// The old value before adding.
189    fn fetch_add(&self, delta: Self::Value) -> Self::Value;
190
191    /// Subtracts a delta from the value, returning the old value.
192    ///
193    /// For integers, uses `Relaxed` ordering by default.
194    /// For floating-point types, uses `AcqRel` ordering (CAS loop).
195    ///
196    /// # Parameters
197    ///
198    /// * `delta` - The value to subtract.
199    ///
200    /// # Returns
201    ///
202    /// The old value before subtracting.
203    fn fetch_sub(&self, delta: Self::Value) -> Self::Value;
204
205    /// Multiplies the value by a factor, returning the old value.
206    ///
207    /// Uses `AcqRel` ordering by default. Implemented via CAS loop.
208    ///
209    /// # Parameters
210    ///
211    /// * `factor` - The value to multiply by.
212    ///
213    /// # Returns
214    ///
215    /// The old value before multiplying.
216    fn fetch_mul(&self, factor: Self::Value) -> Self::Value;
217
218    /// Divides the value by a divisor, returning the old value.
219    ///
220    /// Uses `AcqRel` ordering by default. Implemented via CAS loop.
221    ///
222    /// # Parameters
223    ///
224    /// * `divisor` - The value to divide by.
225    ///
226    /// # Returns
227    ///
228    /// The old value before dividing.
229    fn fetch_div(&self, divisor: Self::Value) -> Self::Value;
230}