Re: [PATCH v5 06/10] rust: sync: atomic: Add the framework of arithmetic operations

Gary Guo <[email protected]>
Newsgroups dev.linux.lists.lkmm,org.kernel.vger.linux-arch,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux
Message-ID <[email protected]>
On Wed, 18 Jun 2025 09:49:30 -0700
Boqun Feng <[email protected]> wrote:

> One important set of atomic operations is the arithmetic operations,
> i.e. add(), sub(), fetch_add(), add_return(), etc. However it may not
> make senses for all the types that `AllowAtomic` to have arithmetic
> operations, for example a `Foo(u32)` may not have a reasonable add() or
> sub(), plus subword types (`u8` and `u16`) currently don't have
> atomic arithmetic operations even on C side and might not have them in
> the future in Rust (because they are usually suboptimal on a few
> architecures). Therefore add a subtrait of `AllowAtomic` describing
> which types have and can do atomic arithemtic operations.
> 
> A few things about this `AllowAtomicArithmetic` trait:
> 
> * It has an associate type `Delta` instead of using
>   `AllowAllowAtomic::Repr` because, a `Bar(u32)` (whose `Repr` is `i32`)
>   may not wants an `add(&self, i32)`, but an `add(&self, u32)`.
> 
> * `AtomicImpl` types already implement an `AtomicHasArithmeticOps`
>   trait, so add blanket implementation for them. In the future, `i8` and
>   `i16` may impl `AtomicImpl` but not `AtomicHasArithmeticOps` if
>   arithemtic operations are not available.
> 
> Only add() and fetch_add() are added. The rest will be added in the
> future.
> 
> Signed-off-by: Boqun Feng <[email protected]>
> ---
>  rust/kernel/sync/atomic/generic.rs | 101 +++++++++++++++++++++++++++++
>  1 file changed, 101 insertions(+)
> 
> diff --git a/rust/kernel/sync/atomic/generic.rs b/rust/kernel/sync/atomic/generic.rs
> index bcdbeea45dd8..8c5bd90b2619 100644
> --- a/rust/kernel/sync/atomic/generic.rs
> +++ b/rust/kernel/sync/atomic/generic.rs
> @@ -57,6 +57,23 @@ fn from_repr(repr: Self::Repr) -> Self {
>      }
>  }
>  
> +/// Atomics that allows arithmetic operations with an integer type.
> +pub trait AllowAtomicArithmetic: AllowAtomic {
> +    /// The delta types for arithmetic operations.
> +    type Delta;
> +
> +    /// Converts [`Self::Delta`] into the representation of the atomic type.
> +    fn delta_into_repr(d: Self::Delta) -> Self::Repr;
> +}
> +
> +impl<T: AtomicImpl + AtomicHasArithmeticOps> AllowAtomicArithmetic for T {
> +    type Delta = Self;
> +
> +    fn delta_into_repr(d: Self::Delta) -> Self::Repr {
> +        d
> +    }
> +}
> +
>  impl<T: AllowAtomic> Atomic<T> {
>      /// Creates a new atomic.
>      pub const fn new(v: T) -> Self {
> @@ -410,3 +427,87 @@ fn try_cmpxchg<Ordering: All>(&self, old: &mut T, new: T, _: Ordering) -> bool {
>          }
>      }
>  }
> +
> +impl<T: AllowAtomicArithmetic> Atomic<T>
> +where
> +    T::Repr: AtomicHasArithmeticOps,
> +{
> +    /// Atomic add.
> +    ///
> +    /// The addition is a wrapping addition.
> +    ///
> +    /// # Examples
> +    ///
> +    /// ```rust
> +    /// use kernel::sync::atomic::{Atomic, Relaxed};
> +    ///
> +    /// let x = Atomic::new(42);
> +    ///
> +    /// assert_eq!(42, x.load(Relaxed));
> +    ///
> +    /// x.add(12, Relaxed);
> +    ///
> +    /// assert_eq!(54, x.load(Relaxed));
> +    /// ```
> +    #[inline(always)]
> +    pub fn add<Ordering: RelaxedOnly>(&self, v: T::Delta, _: Ordering) {

This can be just

pub fn add(&self, v: T::Delta, _: Relaxed)

> +        let v = T::delta_into_repr(v);
> +        let a = self.as_ptr().cast::<T::Repr>();
> +
> +        // SAFETY:
> +        // - For calling the atomic_add() function:
> +        //   - `self.as_ptr()` is a valid pointer, and per the safety requirement of `AllocAtomic`,
> +        //      a `*mut T` is a valid `*mut T::Repr`. Therefore `a` is a valid pointer,
> +        //   - per the type invariants, the following atomic operation won't cause data races.
> +        // - For extra safety requirement of usage on pointers returned by `self.as_ptr():
> +        //   - atomic operations are used here.
> +        unsafe {
> +            T::Repr::atomic_add(a, v);
> +        }
> +    }
> +
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.