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}