Re: [PATCH 08/14] rust: sync: atomic: Add Atomic<{usize,isize}>
Elle Rhumsaa <[email protected]> Sat, 6 Sep 2025 04:24:31 +0000
| Newsgroups | dev.linux.lists.lkmm,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <aLu3f8t53ei4LOLj@archiso> |
On Thu, Sep 04, 2025 at 09:41:35PM -0700, Boqun Feng wrote: > Add generic atomic support for `usize` and `isize`. Note that instead of > mapping directly to `atomic_long_t`, the represention type > (`AtomicType::Repr`) is selected based on CONFIG_64BIT. This reduces > the necessity of creating `atomic_long_*` helpers, which could save > the binary size of kernel if inline helpers are not available. To do so, > an internal type `isize_atomic_repr` is defined, it's `i32` in 32bit > kernel and `i64` in 64bit kernel. > > Reviewed-by: Alice Ryhl <[email protected]> > Reviewed-by: Andreas Hindborg <[email protected]> > Reviewed-by: Benno Lossin <[email protected]> > Signed-off-by: Boqun Feng <[email protected]> > Link: https://lore.kernel.org/all/[email protected]/ > --- > rust/kernel/sync/atomic/predefine.rs | 53 +++++++++++++++++++++++++--- > 1 file changed, 49 insertions(+), 4 deletions(-) > > diff --git a/rust/kernel/sync/atomic/predefine.rs b/rust/kernel/sync/atomic/predefine.rs > index d0875812f6ad..45a17985cda4 100644 > --- a/rust/kernel/sync/atomic/predefine.rs > +++ b/rust/kernel/sync/atomic/predefine.rs > @@ -2,6 +2,9 @@ > > //! Pre-defined atomic types > > +use crate::static_assert; > +use core::mem::{align_of, size_of}; > + > // SAFETY: `i32` has the same size and alignment with itself, and is round-trip transmutable to > // itself. > unsafe impl super::AtomicType for i32 { > @@ -28,6 +31,35 @@ fn rhs_into_delta(rhs: i64) -> i64 { > } > } > > +// Defines an internal type that always maps to the integer type which has the same size alignment > +// as `isize` and `usize`, and `isize` and `usize` are always bi-directional transmutable to > +// `isize_atomic_repr`, which also always implements `AtomicImpl`. > +#[allow(non_camel_case_types)] > +#[cfg(not(CONFIG_64BIT))] > +type isize_atomic_repr = i32; > +#[allow(non_camel_case_types)] > +#[cfg(CONFIG_64BIT)] > +type isize_atomic_repr = i64; > + > +// Ensure size and alignment requirements are checked. > +static_assert!(size_of::<isize>() == size_of::<isize_atomic_repr>()); > +static_assert!(align_of::<isize>() == align_of::<isize_atomic_repr>()); > +static_assert!(size_of::<usize>() == size_of::<isize_atomic_repr>()); > +static_assert!(align_of::<usize>() == align_of::<isize_atomic_repr>()); > + > +// SAFETY: `isize` has the same size and alignment with `isize_atomic_repr`, and is round-trip > +// transmutable to `isize_atomic_repr`. > +unsafe impl super::AtomicType for isize { > + type Repr = isize_atomic_repr; > +} > + > +// SAFETY: The wrapping add result of two `isize_atomic_repr`s is a valid `usize`. > +unsafe impl super::AtomicAdd<isize> for isize { > + fn rhs_into_delta(rhs: isize) -> isize_atomic_repr { > + rhs as isize_atomic_repr > + } > +} > + > // SAFETY: `u32` and `i32` has the same size and alignment, and `u32` is round-trip transmutable to > // `i32`. > unsafe impl super::AtomicType for u32 { > @@ -54,6 +86,19 @@ fn rhs_into_delta(rhs: u64) -> i64 { > } > } > > +// SAFETY: `usize` has the same size and alignment with `isize_atomic_repr`, and is round-trip > +// transmutable to `isize_atomic_repr`. > +unsafe impl super::AtomicType for usize { > + type Repr = isize_atomic_repr; > +} > + > +// SAFETY: The wrapping add result of two `isize_atomic_repr`s is a valid `usize`. > +unsafe impl super::AtomicAdd<usize> for usize { > + fn rhs_into_delta(rhs: usize) -> isize_atomic_repr { > + rhs as isize_atomic_repr > + } > +} > + > use crate::macros::kunit_tests; > > #[kunit_tests(rust_atomics)] > @@ -73,7 +118,7 @@ macro_rules! for_each_type { > > #[test] > fn atomic_basic_tests() { > - for_each_type!(42 in [i32, i64, u32, u64] |v| { > + for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| { > let x = Atomic::new(v); > > assert_eq!(v, x.load(Relaxed)); > @@ -82,7 +127,7 @@ fn atomic_basic_tests() { > > #[test] > fn atomic_xchg_tests() { > - for_each_type!(42 in [i32, i64, u32, u64] |v| { > + for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| { > let x = Atomic::new(v); > > let old = v; > @@ -95,7 +140,7 @@ fn atomic_xchg_tests() { > > #[test] > fn atomic_cmpxchg_tests() { > - for_each_type!(42 in [i32, i64, u32, u64] |v| { > + for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| { > let x = Atomic::new(v); > > let old = v; > @@ -110,7 +155,7 @@ fn atomic_cmpxchg_tests() { > > #[test] > fn atomic_arithmetic_tests() { > - for_each_type!(42 in [i32, i64, u32, u64] |v| { > + for_each_type!(42 in [i32, i64, u32, u64, isize, usize] |v| { > let x = Atomic::new(v); > > assert_eq!(v, x.fetch_add(12, Full)); > -- > 2.51.0 > > Reviewed-by: Elle Rhumsaa <[email protected]>