WIP: rust: sync: atomic: Wire up atomic_ptr_ helpers Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
diff --git a/rust/kernel/sync/atomic/ops.rs b/rust/kernel/sync/atomic/ops.rs index 56e1a0a..a2fc5b0 100644 --- a/rust/kernel/sync/atomic/ops.rs +++ b/rust/kernel/sync/atomic/ops.rs
@@ -15,6 +15,7 @@ pub trait Sealed {} // `i32` and `i64` are only supported atomic implementations. impl private::Sealed for i32 {} impl private::Sealed for i64 {} +impl private::Sealed for *mut crate::ffi::c_void {} /// A marker trait for types that implement atomic operations with C side primitives. /// @@ -23,7 +24,7 @@ impl private::Sealed for i64 {} /// /// - `i32` maps to `atomic_t`. /// - `i64` maps to `atomic64_t`. -pub trait AtomicImpl: Sized + Send + Copy + private::Sealed { +pub trait AtomicImpl: Sized + Copy + private::Sealed { /// The type of the delta in arithmetic or logical operations. /// /// For example, in `atomic_add(ptr, v)`, it's the type of `v`. Usually it's the same type of @@ -41,6 +42,10 @@ impl AtomicImpl for i64 { type Delta = Self; } +impl AtomicImpl for *mut crate::ffi::c_void { + type Delta = isize; +} + /// Atomic representation. pub(super) struct AtomicRepr<T: AtomicImpl>(core::cell::UnsafeCell<T>); @@ -142,7 +147,7 @@ fn [< atomic_ $func >]($($arg: $arg_type,)*) $(-> $ret)? { // Delcares $ops trait with methods and implements the trait for `i32` and `i64`. macro_rules! declare_and_impl_atomic_methods { - ($(#[$attr:meta])* pub trait $ops:ident { + ($(#[$attr:meta])* pub trait $ops:ident [$($rest:tt)*] { $( $(#[doc=$doc:expr])* fn $func:ident [$($variant:ident),*]($($arg_sig:tt)*) $( -> $ret:ty)? { @@ -160,31 +165,58 @@ pub trait $ops: AtomicImpl { )* } - impl $ops for i32 { + declare_and_impl_atomic_methods!(@impl + pub trait $ops [$($rest)*] { + $( + fn $func [$($variant),*]($($arg_sig)*) $( -> $ret)? { + bindings::#call($($arg)*) + } + )* + } + ); + }; + (@impl pub trait $ops:ident [] { + $( + fn $func:ident [$($variant:ident),*]($($arg_sig:tt)*) $( -> $ret:ty)? { + bindings::#call($($arg:tt)*) + } + )* + }) => { + }; + (@impl pub trait $ops:ident [$impl:ty => $c_type:ident $(, $rest_impl:ty => $rest_c_type:ident)*] { + $( + fn $func:ident [$($variant:ident),*]($($arg_sig:tt)*) $( -> $ret:ty)? { + bindings::#call($($arg:tt)*) + } + )* + }) => { + impl $ops for $impl { $( impl_atomic_method!( - (atomic) $func[$($variant)*]($($arg_sig)*) $(-> $ret)? { + ($c_type) $func[$($variant)*]($($arg_sig)*) $(-> $ret)? { call($($arg)*) } ); )* } - impl $ops for i64 { + declare_and_impl_atomic_methods!(@impl + pub trait $ops [$($rest_impl => $rest_c_type),*] { $( - impl_atomic_method!( - (atomic64) $func[$($variant)*]($($arg_sig)*) $(-> $ret)? { - call($($arg)*) - } - ); + fn $func [$($variant),*]($($arg_sig)*) $( -> $ret)? { + bindings::#call($($arg)*) + } )* - } + } + ); } } declare_and_impl_atomic_methods!( /// Basic atomic operations - pub trait AtomicBasicOps { + pub trait AtomicBasicOps + [i32 => atomic, i64 => atomic64, *mut crate::ffi::c_void => atomic_ptr] + { /// Atomic read (load). fn read[acquire](a: &AtomicRepr<Self>) -> Self { // SAFETY: `a.as_ptr()` is valid and properly aligned. @@ -201,7 +233,9 @@ fn set[release](a: &AtomicRepr<Self>, v: Self) { declare_and_impl_atomic_methods!( /// Exchange and compare-and-exchange atomic operations - pub trait AtomicExchangeOps { + pub trait AtomicExchangeOps + [i32 => atomic, i64 => atomic64, *mut crate::ffi::c_void => atomic_ptr] + { /// Atomic exchange. /// /// Atomically updates `*a` to `v` and returns the old value. @@ -228,7 +262,9 @@ fn try_cmpxchg[acquire, release, relaxed]( declare_and_impl_atomic_methods!( /// Atomic arithmetic operations - pub trait AtomicArithmeticOps { + pub trait AtomicArithmeticOps + [i32 => atomic, i64 => atomic64] + { /// Atomic add (wrapping). /// /// Atomically updates `*a` to `(*a).wrapping_add(v)`.