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(CONFIG_64BIT))]
39type isize_atomic_repr = i32;
40#[allow(non_camel_case_types)]
41#[cfg(CONFIG_64BIT)]
42type isize_atomic_repr = i64;
43
44static_assert!(size_of::<isize>() == size_of::<isize_atomic_repr>());
46static_assert!(align_of::<isize>() == align_of::<isize_atomic_repr>());
47static_assert!(size_of::<usize>() == size_of::<isize_atomic_repr>());
48static_assert!(align_of::<usize>() == align_of::<isize_atomic_repr>());
49
50unsafe impl super::AtomicType for isize {
53 type Repr = isize_atomic_repr;
54}
55
56unsafe impl super::AtomicAdd<isize> for isize {
58 fn rhs_into_delta(rhs: isize) -> isize_atomic_repr {
59 rhs as isize_atomic_repr
60 }
61}
62
63unsafe impl super::AtomicType for u32 {
66 type Repr = i32;
67}
68
69unsafe impl super::AtomicAdd<u32> for u32 {
71 fn rhs_into_delta(rhs: u32) -> i32 {
72 rhs as i32
73 }
74}
75
76unsafe impl super::AtomicType for u64 {
79 type Repr = i64;
80}
81
82unsafe impl super::AtomicAdd<u64> for u64 {
84 fn rhs_into_delta(rhs: u64) -> i64 {
85 rhs as i64
86 }
87}
88
89unsafe impl super::AtomicType for usize {
92 type Repr = isize_atomic_repr;
93}
94
95unsafe impl super::AtomicAdd<usize> for usize {
97 fn rhs_into_delta(rhs: usize) -> isize_atomic_repr {
98 rhs as isize_atomic_repr
99 }
100}
101
102use crate::macros::kunit_tests;
103
104#[kunit_tests(rust_atomics)]
105mod tests {
106 use super::super::*;
107
108 macro_rules! for_each_type {
110 ($val:literal in [$($type:ty),*] $fn:expr) => {
111 $({
112 let v: $type = $val;
113
114 $fn(v);
115 })*
116 }
117 }
118
119 #[test]
120 fn atomic_basic_tests() {
121 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
122 let x = Atomic::new(v);
123
124 assert_eq!(v, x.load(Relaxed));
125 });
126 }
127
128 #[test]
129 fn atomic_xchg_tests() {
130 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
131 let x = Atomic::new(v);
132
133 let old = v;
134 let new = v + 1;
135
136 assert_eq!(old, x.xchg(new, Full));
137 assert_eq!(new, x.load(Relaxed));
138 });
139 }
140
141 #[test]
142 fn atomic_cmpxchg_tests() {
143 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
144 let x = Atomic::new(v);
145
146 let old = v;
147 let new = v + 1;
148
149 assert_eq!(Err(old), x.cmpxchg(new, new, Full));
150 assert_eq!(old, x.load(Relaxed));
151 assert_eq!(Ok(old), x.cmpxchg(old, new, Relaxed));
152 assert_eq!(new, x.load(Relaxed));
153 });
154 }
155
156 #[test]
157 fn atomic_arithmetic_tests() {
158 for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| {
159 let x = Atomic::new(v);
160
161 assert_eq!(v, x.fetch_add(12, Full));
162 assert_eq!(v + 12, x.load(Relaxed));
163
164 x.add(13, Relaxed);
165
166 assert_eq!(v + 25, x.load(Relaxed));
167 });
168 }
169}