kernel/sync/atomic/
predefine.rs1use crate::static_assert;
6use core::mem::{align_of, size_of};
7
8unsafe impl super::AtomicType for i32 {
11 type Repr = i32;
12}
13
14unsafe impl super::AtomicAdd<i32> for i32 {
16 fn rhs_into_delta(rhs: i32) -> i32 {
17 rhs
18 }
19}
20
21unsafe impl super::AtomicType for i64 {
24 type Repr = i64;
25}
26
27unsafe impl super::AtomicAdd<i64> for i64 {
29 fn rhs_into_delta(rhs: i64) -> i64 {
30 rhs
31 }
32}
33
34#[allow(non_camel_case_types)]
38#[cfg(not(testlib))]
39#[cfg(not(CONFIG_64BIT))]
40type isize_atomic_repr = i32;
41#[allow(non_camel_case_types)]
42#[cfg(not(testlib))]
43#[cfg(CONFIG_64BIT)]
44type isize_atomic_repr = i64;
45
46#[allow(non_camel_case_types)]
47#[cfg(testlib)]
48#[cfg(target_pointer_width = "32")]
49type isize_atomic_repr = i32;
50#[allow(non_camel_case_types)]
51#[cfg(testlib)]
52#[cfg(target_pointer_width = "64")]
53type isize_atomic_repr = i64;
54
55static_assert!(size_of::<isize>() == size_of::<isize_atomic_repr>());
57static_assert!(align_of::<isize>() == align_of::<isize_atomic_repr>());
58static_assert!(size_of::<usize>() == size_of::<isize_atomic_repr>());
59static_assert!(align_of::<usize>() == align_of::<isize_atomic_repr>());
60
61unsafe impl super::AtomicType for isize {
64 type Repr = isize_atomic_repr;
65}
66
67unsafe impl super::AtomicAdd<isize> for isize {
69 fn rhs_into_delta(rhs: isize) -> isize_atomic_repr {
70 rhs as isize_atomic_repr
71 }
72}
73
74unsafe impl super::AtomicType for u32 {
77 type Repr = i32;
78}
79
80unsafe impl super::AtomicAdd<u32> for u32 {
82 fn rhs_into_delta(rhs: u32) -> i32 {
83 rhs as i32
84 }
85}
86
87unsafe impl super::AtomicType for u64 {
90 type Repr = i64;
91}
92
93unsafe impl super::AtomicAdd<u64> for u64 {
95 fn rhs_into_delta(rhs: u64) -> i64 {
96 rhs as i64
97 }
98}
99
100unsafe impl super::AtomicType for usize {
103 type Repr = isize_atomic_repr;
104}
105
106unsafe impl super::AtomicAdd<usize> for usize {
108 fn rhs_into_delta(rhs: usize) -> isize_atomic_repr {
109 rhs as isize_atomic_repr
110 }
111}
112
113use crate::macros::kunit_tests;
114
115#[kunit_tests(rust_atomics)]
116mod tests {
117 use super::super::*;
118
119 macro_rules! for_each_type {
121 ($val:literal in [$($type:ty),*] $fn:expr) => {
122 $({
123 let v: $type = $val;
124
125 $fn(v);
126 })*
127 }
128 }
129
130 #[test]
131 fn atomic_basic_tests() {
132 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
133 let x = Atomic::new(v);
134
135 assert_eq!(v, x.load(Relaxed));
136 });
137 }
138
139 #[test]
140 fn atomic_xchg_tests() {
141 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
142 let x = Atomic::new(v);
143
144 let old = v;
145 let new = v + 1;
146
147 assert_eq!(old, x.xchg(new, Full));
148 assert_eq!(new, x.load(Relaxed));
149 });
150 }
151
152 #[test]
153 fn atomic_cmpxchg_tests() {
154 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
155 let x = Atomic::new(v);
156
157 let old = v;
158 let new = v + 1;
159
160 assert_eq!(Err(old), x.cmpxchg(new, new, Full));
161 assert_eq!(old, x.load(Relaxed));
162 assert_eq!(Ok(old), x.cmpxchg(old, new, Relaxed));
163 assert_eq!(new, x.load(Relaxed));
164 });
165 }
166
167 #[test]
168 fn atomic_arithmetic_tests() {
169 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
170 let x = Atomic::new(v);
171
172 assert_eq!(v, x.fetch_add(12, Full));
173 assert_eq!(v + 12, x.load(Relaxed));
174
175 x.add(13, Relaxed);
176
177 assert_eq!(v + 25, x.load(Relaxed));
178 });
179 }
180}