kernel/sync/atomic/
predefine.rs1use crate::static_assert;
6use core::mem::{align_of, size_of};
7
8static_assert!(size_of::<bool>() == size_of::<i8>());
10static_assert!(align_of::<bool>() == align_of::<i8>());
11
12unsafe impl super::AtomicType for bool {
16 type Repr = i8;
17}
18
19unsafe impl super::AtomicType for i8 {
22 type Repr = i8;
23}
24
25unsafe impl super::AtomicType for i16 {
28 type Repr = i16;
29}
30
31unsafe impl super::AtomicType for i32 {
34 type Repr = i32;
35}
36
37unsafe impl super::AtomicAdd<i32> for i32 {
39 fn rhs_into_delta(rhs: i32) -> i32 {
40 rhs
41 }
42}
43
44unsafe impl super::AtomicType for i64 {
47 type Repr = i64;
48}
49
50unsafe impl super::AtomicAdd<i64> for i64 {
52 fn rhs_into_delta(rhs: i64) -> i64 {
53 rhs
54 }
55}
56
57#[allow(non_camel_case_types)]
61#[cfg(not(testlib))]
62#[cfg(not(CONFIG_64BIT))]
63type isize_atomic_repr = i32;
64#[allow(non_camel_case_types)]
65#[cfg(not(testlib))]
66#[cfg(CONFIG_64BIT)]
67type isize_atomic_repr = i64;
68
69#[allow(non_camel_case_types)]
70#[cfg(testlib)]
71#[cfg(target_pointer_width = "32")]
72type isize_atomic_repr = i32;
73#[allow(non_camel_case_types)]
74#[cfg(testlib)]
75#[cfg(target_pointer_width = "64")]
76type isize_atomic_repr = i64;
77
78static_assert!(size_of::<isize>() == size_of::<isize_atomic_repr>());
80static_assert!(align_of::<isize>() == align_of::<isize_atomic_repr>());
81static_assert!(size_of::<usize>() == size_of::<isize_atomic_repr>());
82static_assert!(align_of::<usize>() == align_of::<isize_atomic_repr>());
83
84unsafe impl super::AtomicType for isize {
87 type Repr = isize_atomic_repr;
88}
89
90unsafe impl super::AtomicAdd<isize> for isize {
92 fn rhs_into_delta(rhs: isize) -> isize_atomic_repr {
93 rhs as isize_atomic_repr
94 }
95}
96
97unsafe impl super::AtomicType for u32 {
100 type Repr = i32;
101}
102
103unsafe impl super::AtomicAdd<u32> for u32 {
105 fn rhs_into_delta(rhs: u32) -> i32 {
106 rhs as i32
107 }
108}
109
110unsafe impl super::AtomicType for u64 {
113 type Repr = i64;
114}
115
116unsafe impl super::AtomicAdd<u64> for u64 {
118 fn rhs_into_delta(rhs: u64) -> i64 {
119 rhs as i64
120 }
121}
122
123unsafe impl super::AtomicType for usize {
126 type Repr = isize_atomic_repr;
127}
128
129unsafe impl super::AtomicAdd<usize> for usize {
131 fn rhs_into_delta(rhs: usize) -> isize_atomic_repr {
132 rhs as isize_atomic_repr
133 }
134}
135
136use crate::macros::kunit_tests;
137
138#[kunit_tests(rust_atomics)]
139mod tests {
140 use super::super::*;
141
142 macro_rules! for_each_type {
144 ($val:literal in [$($type:ty),*] $fn:expr) => {
145 $({
146 let v: $type = $val;
147
148 $fn(v);
149 })*
150 }
151 }
152
153 #[test]
154 fn atomic_basic_tests() {
155 for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| {
156 let x = Atomic::new(v);
157
158 assert_eq!(v, x.load(Relaxed));
159 });
160 }
161
162 #[test]
163 fn atomic_acquire_release_tests() {
164 for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| {
165 let x = Atomic::new(0);
166
167 x.store(v, Release);
168 assert_eq!(v, x.load(Acquire));
169 });
170 }
171
172 #[test]
173 fn atomic_xchg_tests() {
174 for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| {
175 let x = Atomic::new(v);
176
177 let old = v;
178 let new = v + 1;
179
180 assert_eq!(old, x.xchg(new, Full));
181 assert_eq!(new, x.load(Relaxed));
182 });
183 }
184
185 #[test]
186 fn atomic_cmpxchg_tests() {
187 for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| {
188 let x = Atomic::new(v);
189
190 let old = v;
191 let new = v + 1;
192
193 assert_eq!(Err(old), x.cmpxchg(new, new, Full));
194 assert_eq!(old, x.load(Relaxed));
195 assert_eq!(Ok(old), x.cmpxchg(old, new, Relaxed));
196 assert_eq!(new, x.load(Relaxed));
197 });
198 }
199
200 #[test]
201 fn atomic_arithmetic_tests() {
202 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
203 let x = Atomic::new(v);
204
205 assert_eq!(v, x.fetch_add(12, Full));
206 assert_eq!(v + 12, x.load(Relaxed));
207
208 x.add(13, Relaxed);
209
210 assert_eq!(v + 25, x.load(Relaxed));
211 });
212 }
213
214 #[test]
215 fn atomic_bool_tests() {
216 let x = Atomic::new(false);
217
218 assert_eq!(false, x.load(Relaxed));
219 x.store(true, Relaxed);
220 assert_eq!(true, x.load(Relaxed));
221
222 assert_eq!(true, x.xchg(false, Relaxed));
223 assert_eq!(false, x.load(Relaxed));
224
225 assert_eq!(Err(false), x.cmpxchg(true, true, Relaxed));
226 assert_eq!(false, x.load(Relaxed));
227 assert_eq!(Ok(false), x.cmpxchg(false, true, Full));
228 }
229}