Thread (26 messages) 26 messages, 4 authors, 6d ago

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help