[PATCH RFC 02/11] rust: sync: atomic: Add Atomic<u{8,16}>
flat view
COOLING6d
From: Thomas Weißschuh <linux@weissschuh.net>
Date: 2026-10-11 12:53:08
Also in:
driver-core, linux-kselftest, lkml, rust-for-linux
Subsystem:
atomic infrastructure, rust, rust [sync], the rest · Maintainers:
Will Deacon, Peter Zijlstra, Boqun Feng, Miguel Ojeda, Gary Guo, Alice Ryhl, Linus Torvalds
Add generic atomic support for small unsigned integers that have an `AtomicImpl` with the same size and alignment. Also extend the unit tests. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> --- rust/kernel/sync/atomic/predefine.rs | 44 ++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-)
diff --git a/rust/kernel/sync/atomic/predefine.rs b/rust/kernel/sync/atomic/predefine.rs
index 3d63f40791fa..4c1fb5e08dc2 100644
--- a/rust/kernel/sync/atomic/predefine.rs
+++ b/rust/kernel/sync/atomic/predefine.rs@@ -113,6 +113,32 @@ fn rhs_into_delta(rhs: isize) -> isize_atomic_repr { } } +// SAFETY: `u8` and `i8` has the same size and alignment, and `u8` is round-trip transmutable to +// `i8`. +unsafe impl super::AtomicType for u8 { + type Repr = i8; +} + +// SAFETY: The wrapping add result of two `i8`s is a valid `u8`. +unsafe impl super::AtomicAdd<u8> for u8 { + fn rhs_into_delta(rhs: u8) -> i8 { + rhs as i8 + } +} + +// SAFETY: `u16` and `i16` has the same size and alignment, and `u16` is round-trip transmutable to +// `i16`. +unsafe impl super::AtomicType for u16 { + type Repr = i16; +} + +// SAFETY: The wrapping add result of two `i16`s is a valid `u16`. +unsafe impl super::AtomicAdd<u16> for u16 { + fn rhs_into_delta(rhs: u16) -> i16 { + rhs as i16 + } +} + // SAFETY: `u32` and `i32` has the same size and alignment, and `u32` is round-trip transmutable to // `i32`. unsafe impl super::AtomicType for u32 {
@@ -170,13 +196,13 @@ macro_rules! for_each_type { #[test] fn atomic_basic_tests() { - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(v); assert_eq!(v, x.load(Relaxed)); }); - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(v); let ptr = x.as_ptr();
@@ -187,14 +213,14 @@ fn atomic_basic_tests() { #[test] fn atomic_acquire_release_tests() { - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(0); x.store(v, Release); assert_eq!(v, x.load(Acquire)); }); - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(0); let ptr = x.as_ptr();
@@ -208,7 +234,7 @@ fn atomic_acquire_release_tests() { #[test] fn atomic_xchg_tests() { - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(v); let old = v;
@@ -218,7 +244,7 @@ fn atomic_xchg_tests() { assert_eq!(new, x.load(Relaxed)); }); - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(v); let ptr = x.as_ptr();
@@ -233,7 +259,7 @@ fn atomic_xchg_tests() { #[test] fn atomic_cmpxchg_tests() { - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(v); let old = v;
@@ -245,7 +271,7 @@ fn atomic_cmpxchg_tests() { assert_eq!(new, x.load(Relaxed)); }); - for_each_type!(42 in [i8, i16, i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i8, i16, i32, i64, u8, u16, u32, u64, isize, usize] |v| { let x = Atomic::new(v); let ptr = x.as_ptr();
@@ -263,7 +289,7 @@ fn atomic_cmpxchg_tests() { #[test] fn atomic_arithmetic_tests() { - for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| { + for_each_type!(42 in [i32, i64, u64, isize, usize] |v| { let x = Atomic::new(v); assert_eq!(v, x.fetch_add(12, Full));
--
2.56.0