xref: /linux-6.15/rust/kernel/sync/arc.rs (revision dbd5058b)
19dc04365SWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0
29dc04365SWedson Almeida Filho 
39dc04365SWedson Almeida Filho //! A reference-counted pointer.
49dc04365SWedson Almeida Filho //!
59dc04365SWedson Almeida Filho //! This module implements a way for users to create reference-counted objects and pointers to
69dc04365SWedson Almeida Filho //! them. Such a pointer automatically increments and decrements the count, and drops the
79dc04365SWedson Almeida Filho //! underlying object when it reaches zero. It is also safe to use concurrently from multiple
89dc04365SWedson Almeida Filho //! threads.
99dc04365SWedson Almeida Filho //!
109dc04365SWedson Almeida Filho //! It is different from the standard library's [`Arc`] in a few ways:
119dc04365SWedson Almeida Filho //! 1. It is backed by the kernel's `refcount_t` type.
129dc04365SWedson Almeida Filho //! 2. It does not support weak references, which allows it to be half the size.
139dc04365SWedson Almeida Filho //! 3. It saturates the reference count instead of aborting when it goes over a threshold.
149dc04365SWedson Almeida Filho //! 4. It does not provide a `get_mut` method, so the ref counted object is pinned.
1508f983a5SAlex Mantel //! 5. The object in [`Arc`] is pinned implicitly.
169dc04365SWedson Almeida Filho //!
179dc04365SWedson Almeida Filho //! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
189dc04365SWedson Almeida Filho 
190c7ae432SWedson Almeida Filho use crate::{
208373147cSDanilo Krummrich     alloc::{AllocError, Flags, KBox},
2108f983a5SAlex Mantel     bindings,
22*dbd5058bSBenno Lossin     init::InPlaceInit,
23701608bdSBenno Lossin     try_init,
240c7ae432SWedson Almeida Filho     types::{ForeignOwnable, Opaque},
250c7ae432SWedson Almeida Filho };
26f75cb6fcSWedson Almeida Filho use core::{
272c109285SWedson Almeida Filho     alloc::Layout,
2800140a83SBoqun Feng     fmt,
2947cb6bf7SXiangfei Ding     marker::PhantomData,
3070e42ebbSWedson Almeida Filho     mem::{ManuallyDrop, MaybeUninit},
3170e42ebbSWedson Almeida Filho     ops::{Deref, DerefMut},
3270e42ebbSWedson Almeida Filho     pin::Pin,
3344f2e626SAlice Ryhl     ptr::NonNull,
34f75cb6fcSWedson Almeida Filho };
35*dbd5058bSBenno Lossin use pin_init::{self, pin_data, InPlaceWrite, Init, PinInit};
369dc04365SWedson Almeida Filho 
371edd0337SAsahi Lina mod std_vendor;
381edd0337SAsahi Lina 
399dc04365SWedson Almeida Filho /// A reference-counted pointer to an instance of `T`.
409dc04365SWedson Almeida Filho ///
419dc04365SWedson Almeida Filho /// The reference count is incremented when new instances of [`Arc`] are created, and decremented
429dc04365SWedson Almeida Filho /// when they are dropped. When the count reaches zero, the underlying `T` is also dropped.
439dc04365SWedson Almeida Filho ///
449dc04365SWedson Almeida Filho /// # Invariants
459dc04365SWedson Almeida Filho ///
469dc04365SWedson Almeida Filho /// The reference count on an instance of [`Arc`] is always non-zero.
479dc04365SWedson Almeida Filho /// The object pointed to by [`Arc`] is always pinned.
489dc04365SWedson Almeida Filho ///
499dc04365SWedson Almeida Filho /// # Examples
509dc04365SWedson Almeida Filho ///
519dc04365SWedson Almeida Filho /// ```
529dc04365SWedson Almeida Filho /// use kernel::sync::Arc;
539dc04365SWedson Almeida Filho ///
549dc04365SWedson Almeida Filho /// struct Example {
559dc04365SWedson Almeida Filho ///     a: u32,
569dc04365SWedson Almeida Filho ///     b: u32,
579dc04365SWedson Almeida Filho /// }
589dc04365SWedson Almeida Filho ///
59ebf2b8a7SValentin Obst /// // Create a refcounted instance of `Example`.
60cc41670eSWedson Almeida Filho /// let obj = Arc::new(Example { a: 10, b: 20 }, GFP_KERNEL)?;
619dc04365SWedson Almeida Filho ///
629dc04365SWedson Almeida Filho /// // Get a new pointer to `obj` and increment the refcount.
639dc04365SWedson Almeida Filho /// let cloned = obj.clone();
649dc04365SWedson Almeida Filho ///
659dc04365SWedson Almeida Filho /// // Assert that both `obj` and `cloned` point to the same underlying object.
669dc04365SWedson Almeida Filho /// assert!(core::ptr::eq(&*obj, &*cloned));
679dc04365SWedson Almeida Filho ///
689dc04365SWedson Almeida Filho /// // Destroy `obj` and decrement its refcount.
699dc04365SWedson Almeida Filho /// drop(obj);
709dc04365SWedson Almeida Filho ///
719dc04365SWedson Almeida Filho /// // Check that the values are still accessible through `cloned`.
729dc04365SWedson Almeida Filho /// assert_eq!(cloned.a, 10);
739dc04365SWedson Almeida Filho /// assert_eq!(cloned.b, 20);
749dc04365SWedson Almeida Filho ///
759dc04365SWedson Almeida Filho /// // The refcount drops to zero when `cloned` goes out of scope, and the memory is freed.
76bfa7dff0SMiguel Ojeda /// # Ok::<(), Error>(())
779dc04365SWedson Almeida Filho /// ```
7853528772SWedson Almeida Filho ///
7953528772SWedson Almeida Filho /// Using `Arc<T>` as the type of `self`:
8053528772SWedson Almeida Filho ///
8153528772SWedson Almeida Filho /// ```
8253528772SWedson Almeida Filho /// use kernel::sync::Arc;
8353528772SWedson Almeida Filho ///
8453528772SWedson Almeida Filho /// struct Example {
8553528772SWedson Almeida Filho ///     a: u32,
8653528772SWedson Almeida Filho ///     b: u32,
8753528772SWedson Almeida Filho /// }
8853528772SWedson Almeida Filho ///
8953528772SWedson Almeida Filho /// impl Example {
9053528772SWedson Almeida Filho ///     fn take_over(self: Arc<Self>) {
9153528772SWedson Almeida Filho ///         // ...
9253528772SWedson Almeida Filho ///     }
9353528772SWedson Almeida Filho ///
9453528772SWedson Almeida Filho ///     fn use_reference(self: &Arc<Self>) {
9553528772SWedson Almeida Filho ///         // ...
9653528772SWedson Almeida Filho ///     }
9753528772SWedson Almeida Filho /// }
9853528772SWedson Almeida Filho ///
99cc41670eSWedson Almeida Filho /// let obj = Arc::new(Example { a: 10, b: 20 }, GFP_KERNEL)?;
10053528772SWedson Almeida Filho /// obj.use_reference();
10153528772SWedson Almeida Filho /// obj.take_over();
102bfa7dff0SMiguel Ojeda /// # Ok::<(), Error>(())
10353528772SWedson Almeida Filho /// ```
104f75cb6fcSWedson Almeida Filho ///
105f75cb6fcSWedson Almeida Filho /// Coercion from `Arc<Example>` to `Arc<dyn MyTrait>`:
106f75cb6fcSWedson Almeida Filho ///
107f75cb6fcSWedson Almeida Filho /// ```
1080748424aSWedson Almeida Filho /// use kernel::sync::{Arc, ArcBorrow};
109f75cb6fcSWedson Almeida Filho ///
1100748424aSWedson Almeida Filho /// trait MyTrait {
1110748424aSWedson Almeida Filho ///     // Trait has a function whose `self` type is `Arc<Self>`.
1120748424aSWedson Almeida Filho ///     fn example1(self: Arc<Self>) {}
1130748424aSWedson Almeida Filho ///
1140748424aSWedson Almeida Filho ///     // Trait has a function whose `self` type is `ArcBorrow<'_, Self>`.
1150748424aSWedson Almeida Filho ///     fn example2(self: ArcBorrow<'_, Self>) {}
1160748424aSWedson Almeida Filho /// }
117f75cb6fcSWedson Almeida Filho ///
118f75cb6fcSWedson Almeida Filho /// struct Example;
119f75cb6fcSWedson Almeida Filho /// impl MyTrait for Example {}
120f75cb6fcSWedson Almeida Filho ///
121f75cb6fcSWedson Almeida Filho /// // `obj` has type `Arc<Example>`.
122cc41670eSWedson Almeida Filho /// let obj: Arc<Example> = Arc::new(Example, GFP_KERNEL)?;
123f75cb6fcSWedson Almeida Filho ///
124f75cb6fcSWedson Almeida Filho /// // `coerced` has type `Arc<dyn MyTrait>`.
125f75cb6fcSWedson Almeida Filho /// let coerced: Arc<dyn MyTrait> = obj;
126bfa7dff0SMiguel Ojeda /// # Ok::<(), Error>(())
127f75cb6fcSWedson Almeida Filho /// ```
12847cb6bf7SXiangfei Ding #[repr(transparent)]
12947cb6bf7SXiangfei Ding #[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, derive(core::marker::CoercePointee))]
1309dc04365SWedson Almeida Filho pub struct Arc<T: ?Sized> {
1319dc04365SWedson Almeida Filho     ptr: NonNull<ArcInner<T>>,
1322dde1c8bSTamir Duberstein     // NB: this informs dropck that objects of type `ArcInner<T>` may be used in `<Arc<T> as
1332dde1c8bSTamir Duberstein     // Drop>::drop`. Note that dropck already assumes that objects of type `T` may be used in
1342dde1c8bSTamir Duberstein     // `<Arc<T> as Drop>::drop` and the distinction between `T` and `ArcInner<T>` is not presently
1352dde1c8bSTamir Duberstein     // meaningful with respect to dropck - but this may change in the future so this is left here
1362dde1c8bSTamir Duberstein     // out of an abundance of caution.
1372dde1c8bSTamir Duberstein     //
1382dde1c8bSTamir Duberstein     // See https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-drop-checking
1392dde1c8bSTamir Duberstein     // for more detail on the semantics of dropck in the presence of `PhantomData`.
1409dc04365SWedson Almeida Filho     _p: PhantomData<ArcInner<T>>,
1419dc04365SWedson Almeida Filho }
1429dc04365SWedson Almeida Filho 
143701608bdSBenno Lossin #[pin_data]
1449dc04365SWedson Almeida Filho #[repr(C)]
1459dc04365SWedson Almeida Filho struct ArcInner<T: ?Sized> {
1469dc04365SWedson Almeida Filho     refcount: Opaque<bindings::refcount_t>,
1479dc04365SWedson Almeida Filho     data: T,
1489dc04365SWedson Almeida Filho }
1499dc04365SWedson Almeida Filho 
15051f6af86SAlice Ryhl impl<T: ?Sized> ArcInner<T> {
15151f6af86SAlice Ryhl     /// Converts a pointer to the contents of an [`Arc`] into a pointer to the [`ArcInner`].
15251f6af86SAlice Ryhl     ///
15351f6af86SAlice Ryhl     /// # Safety
15451f6af86SAlice Ryhl     ///
15551f6af86SAlice Ryhl     /// `ptr` must have been returned by a previous call to [`Arc::into_raw`], and the `Arc` must
15651f6af86SAlice Ryhl     /// not yet have been destroyed.
container_of(ptr: *const T) -> NonNull<ArcInner<T>>15751f6af86SAlice Ryhl     unsafe fn container_of(ptr: *const T) -> NonNull<ArcInner<T>> {
15851f6af86SAlice Ryhl         let refcount_layout = Layout::new::<bindings::refcount_t>();
15951f6af86SAlice Ryhl         // SAFETY: The caller guarantees that the pointer is valid.
16051f6af86SAlice Ryhl         let val_layout = Layout::for_value(unsafe { &*ptr });
16151f6af86SAlice Ryhl         // SAFETY: We're computing the layout of a real struct that existed when compiling this
16251f6af86SAlice Ryhl         // binary, so its layout is not so large that it can trigger arithmetic overflow.
16351f6af86SAlice Ryhl         let val_offset = unsafe { refcount_layout.extend(val_layout).unwrap_unchecked().1 };
16451f6af86SAlice Ryhl 
16551f6af86SAlice Ryhl         // Pointer casts leave the metadata unchanged. This is okay because the metadata of `T` and
16651f6af86SAlice Ryhl         // `ArcInner<T>` is the same since `ArcInner` is a struct with `T` as its last field.
16751f6af86SAlice Ryhl         //
16851f6af86SAlice Ryhl         // This is documented at:
16951f6af86SAlice Ryhl         // <https://doc.rust-lang.org/std/ptr/trait.Pointee.html>.
17051f6af86SAlice Ryhl         let ptr = ptr as *const ArcInner<T>;
17151f6af86SAlice Ryhl 
17251f6af86SAlice Ryhl         // SAFETY: The pointer is in-bounds of an allocation both before and after offsetting the
17351f6af86SAlice Ryhl         // pointer, since it originates from a previous call to `Arc::into_raw` on an `Arc` that is
17451f6af86SAlice Ryhl         // still valid.
17551f6af86SAlice Ryhl         let ptr = unsafe { ptr.byte_sub(val_offset) };
17651f6af86SAlice Ryhl 
17751f6af86SAlice Ryhl         // SAFETY: The pointer can't be null since you can't have an `ArcInner<T>` value at the null
17851f6af86SAlice Ryhl         // address.
17951f6af86SAlice Ryhl         unsafe { NonNull::new_unchecked(ptr.cast_mut()) }
18051f6af86SAlice Ryhl     }
18151f6af86SAlice Ryhl }
18251f6af86SAlice Ryhl 
183f75cb6fcSWedson Almeida Filho // This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the
184f75cb6fcSWedson Almeida Filho // dynamically-sized type (DST) `U`.
18547cb6bf7SXiangfei Ding #[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
18647cb6bf7SXiangfei Ding impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {}
187f75cb6fcSWedson Almeida Filho 
1880748424aSWedson Almeida Filho // This is to allow `Arc<U>` to be dispatched on when `Arc<T>` can be coerced into `Arc<U>`.
18947cb6bf7SXiangfei Ding #[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
19047cb6bf7SXiangfei Ding impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<Arc<U>> for Arc<T> {}
1910748424aSWedson Almeida Filho 
1929dc04365SWedson Almeida Filho // SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because
1939dc04365SWedson Almeida Filho // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
194f8110cd1SAlice Ryhl // `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` using a
195f8110cd1SAlice Ryhl // mutable reference when the reference count reaches zero and `T` is dropped.
1969dc04365SWedson Almeida Filho unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
1979dc04365SWedson Almeida Filho 
198d701e061SAlice Ryhl // SAFETY: It is safe to send `&Arc<T>` to another thread when the underlying `T` is `Sync`
199d701e061SAlice Ryhl // because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
200d701e061SAlice Ryhl // it needs `T` to be `Send` because any thread that has a `&Arc<T>` may clone it and get an
201d701e061SAlice Ryhl // `Arc<T>` on that thread, so the thread may ultimately access `T` using a mutable reference when
202d701e061SAlice Ryhl // the reference count reaches zero and `T` is dropped.
2039dc04365SWedson Almeida Filho unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
2049dc04365SWedson Almeida Filho 
205114ca41fSBenno Lossin impl<T> InPlaceInit<T> for Arc<T> {
206114ca41fSBenno Lossin     type PinnedSelf = Self;
207114ca41fSBenno Lossin 
208114ca41fSBenno Lossin     #[inline]
try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> where E: From<AllocError>,209114ca41fSBenno Lossin     fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
210114ca41fSBenno Lossin     where
211114ca41fSBenno Lossin         E: From<AllocError>,
212114ca41fSBenno Lossin     {
213114ca41fSBenno Lossin         UniqueArc::try_pin_init(init, flags).map(|u| u.into())
214114ca41fSBenno Lossin     }
215114ca41fSBenno Lossin 
216114ca41fSBenno Lossin     #[inline]
try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> where E: From<AllocError>,217114ca41fSBenno Lossin     fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
218114ca41fSBenno Lossin     where
219114ca41fSBenno Lossin         E: From<AllocError>,
220114ca41fSBenno Lossin     {
221114ca41fSBenno Lossin         UniqueArc::try_init(init, flags).map(|u| u.into())
222114ca41fSBenno Lossin     }
223114ca41fSBenno Lossin }
224114ca41fSBenno Lossin 
2259dc04365SWedson Almeida Filho impl<T> Arc<T> {
2269dc04365SWedson Almeida Filho     /// Constructs a new reference counted instance of `T`.
new(contents: T, flags: Flags) -> Result<Self, AllocError>227cc41670eSWedson Almeida Filho     pub fn new(contents: T, flags: Flags) -> Result<Self, AllocError> {
2289dc04365SWedson Almeida Filho         // INVARIANT: The refcount is initialised to a non-zero value.
2299dc04365SWedson Almeida Filho         let value = ArcInner {
2309dc04365SWedson Almeida Filho             // SAFETY: There are no safety requirements for this FFI call.
2319dc04365SWedson Almeida Filho             refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }),
2329dc04365SWedson Almeida Filho             data: contents,
2339dc04365SWedson Almeida Filho         };
2349dc04365SWedson Almeida Filho 
2358373147cSDanilo Krummrich         let inner = KBox::new(value, flags)?;
236aa991a2aSTamir Duberstein         let inner = KBox::leak(inner).into();
2379dc04365SWedson Almeida Filho 
2389dc04365SWedson Almeida Filho         // SAFETY: We just created `inner` with a reference count of 1, which is owned by the new
2399dc04365SWedson Almeida Filho         // `Arc` object.
240aa991a2aSTamir Duberstein         Ok(unsafe { Self::from_inner(inner) })
2419dc04365SWedson Almeida Filho     }
2429dc04365SWedson Almeida Filho }
2439dc04365SWedson Almeida Filho 
2449dc04365SWedson Almeida Filho impl<T: ?Sized> Arc<T> {
2459dc04365SWedson Almeida Filho     /// Constructs a new [`Arc`] from an existing [`ArcInner`].
2469dc04365SWedson Almeida Filho     ///
2479dc04365SWedson Almeida Filho     /// # Safety
2489dc04365SWedson Almeida Filho     ///
2499dc04365SWedson Almeida Filho     /// The caller must ensure that `inner` points to a valid location and has a non-zero reference
2509dc04365SWedson Almeida Filho     /// count, one of which will be owned by the new [`Arc`] instance.
from_inner(inner: NonNull<ArcInner<T>>) -> Self2519dc04365SWedson Almeida Filho     unsafe fn from_inner(inner: NonNull<ArcInner<T>>) -> Self {
2529dc04365SWedson Almeida Filho         // INVARIANT: By the safety requirements, the invariants hold.
2539dc04365SWedson Almeida Filho         Arc {
2549dc04365SWedson Almeida Filho             ptr: inner,
2559dc04365SWedson Almeida Filho             _p: PhantomData,
2569dc04365SWedson Almeida Filho         }
2579dc04365SWedson Almeida Filho     }
25817f67160SWedson Almeida Filho 
259a8321776SWedson Almeida Filho     /// Convert the [`Arc`] into a raw pointer.
260a8321776SWedson Almeida Filho     ///
261a8321776SWedson Almeida Filho     /// The raw pointer has ownership of the refcount that this Arc object owned.
into_raw(self) -> *const T262a8321776SWedson Almeida Filho     pub fn into_raw(self) -> *const T {
263a8321776SWedson Almeida Filho         let ptr = self.ptr.as_ptr();
264a8321776SWedson Almeida Filho         core::mem::forget(self);
265a8321776SWedson Almeida Filho         // SAFETY: The pointer is valid.
266a8321776SWedson Almeida Filho         unsafe { core::ptr::addr_of!((*ptr).data) }
267a8321776SWedson Almeida Filho     }
268a8321776SWedson Almeida Filho 
269a8321776SWedson Almeida Filho     /// Return a raw pointer to the data in this arc.
as_ptr(this: &Self) -> *const T270a8321776SWedson Almeida Filho     pub fn as_ptr(this: &Self) -> *const T {
271a8321776SWedson Almeida Filho         let ptr = this.ptr.as_ptr();
272a8321776SWedson Almeida Filho 
273a8321776SWedson Almeida Filho         // SAFETY: As `ptr` points to a valid allocation of type `ArcInner`,
274a8321776SWedson Almeida Filho         // field projection to `data`is within bounds of the allocation.
275a8321776SWedson Almeida Filho         unsafe { core::ptr::addr_of!((*ptr).data) }
27651f6af86SAlice Ryhl     }
27751f6af86SAlice Ryhl 
27851f6af86SAlice Ryhl     /// Recreates an [`Arc`] instance previously deconstructed via [`Arc::into_raw`].
279a8321776SWedson Almeida Filho     ///
280a8321776SWedson Almeida Filho     /// # Safety
281a8321776SWedson Almeida Filho     ///
28251f6af86SAlice Ryhl     /// `ptr` must have been returned by a previous call to [`Arc::into_raw`]. Additionally, it
283a8321776SWedson Almeida Filho     /// must not be called more than once for each previous call to [`Arc::into_raw`].
from_raw(ptr: *const T) -> Self284a8321776SWedson Almeida Filho     pub unsafe fn from_raw(ptr: *const T) -> Self {
28517f67160SWedson Almeida Filho         // SAFETY: The caller promises that this pointer originates from a call to `into_raw` on an
28617f67160SWedson Almeida Filho         // `Arc` that is still valid.
28717f67160SWedson Almeida Filho         let ptr = unsafe { ArcInner::container_of(ptr) };
28817f67160SWedson Almeida Filho 
28917f67160SWedson Almeida Filho         // SAFETY: By the safety requirements we know that `ptr` came from `Arc::into_raw`, so the
29017f67160SWedson Almeida Filho         // reference count held then will be owned by the new `Arc` object.
29117f67160SWedson Almeida Filho         unsafe { Self::from_inner(ptr) }
29217f67160SWedson Almeida Filho     }
29317f67160SWedson Almeida Filho 
29417f67160SWedson Almeida Filho     /// Returns an [`ArcBorrow`] from the given [`Arc`].
29517f67160SWedson Almeida Filho     ///
296bd780aeaSAlice Ryhl     /// This is useful when the argument of a function call is an [`ArcBorrow`] (e.g., in a method
297bd780aeaSAlice Ryhl     /// receiver), but we have an [`Arc`] instead. Getting an [`ArcBorrow`] is free when optimised.
298bd780aeaSAlice Ryhl     #[inline]
as_arc_borrow(&self) -> ArcBorrow<'_, T>299bd780aeaSAlice Ryhl     pub fn as_arc_borrow(&self) -> ArcBorrow<'_, T> {
300bd780aeaSAlice Ryhl         // SAFETY: The constraint that the lifetime of the shared reference must outlive that of
301a0a4e170SAlice Ryhl         // the returned `ArcBorrow` ensures that the object remains alive and that no mutable
302a0a4e170SAlice Ryhl         // reference can be created.
303a0a4e170SAlice Ryhl         unsafe { ArcBorrow::new(self.ptr) }
304a0a4e170SAlice Ryhl     }
305a0a4e170SAlice Ryhl 
306a0a4e170SAlice Ryhl     /// Compare whether two [`Arc`] pointers reference the same underlying object.
ptr_eq(this: &Self, other: &Self) -> bool307a0a4e170SAlice Ryhl     pub fn ptr_eq(this: &Self, other: &Self) -> bool {
308a0a4e170SAlice Ryhl         core::ptr::eq(this.ptr.as_ptr(), other.ptr.as_ptr())
309a0a4e170SAlice Ryhl     }
310a0a4e170SAlice Ryhl 
311a0a4e170SAlice Ryhl     /// Converts this [`Arc`] into a [`UniqueArc`], or destroys it if it is not unique.
312a0a4e170SAlice Ryhl     ///
313a0a4e170SAlice Ryhl     /// When this destroys the `Arc`, it does so while properly avoiding races. This means that
314a0a4e170SAlice Ryhl     /// this method will never call the destructor of the value.
315a0a4e170SAlice Ryhl     ///
316a0a4e170SAlice Ryhl     /// # Examples
317a0a4e170SAlice Ryhl     ///
318a0a4e170SAlice Ryhl     /// ```
319a0a4e170SAlice Ryhl     /// use kernel::sync::{Arc, UniqueArc};
320a0a4e170SAlice Ryhl     ///
321a0a4e170SAlice Ryhl     /// let arc = Arc::new(42, GFP_KERNEL)?;
322a0a4e170SAlice Ryhl     /// let unique_arc = arc.into_unique_or_drop();
323a0a4e170SAlice Ryhl     ///
324a0a4e170SAlice Ryhl     /// // The above conversion should succeed since refcount of `arc` is 1.
325a0a4e170SAlice Ryhl     /// assert!(unique_arc.is_some());
326a0a4e170SAlice Ryhl     ///
327a0a4e170SAlice Ryhl     /// assert_eq!(*(unique_arc.unwrap()), 42);
328a0a4e170SAlice Ryhl     ///
329a0a4e170SAlice Ryhl     /// # Ok::<(), Error>(())
330a0a4e170SAlice Ryhl     /// ```
331a0a4e170SAlice Ryhl     ///
332a0a4e170SAlice Ryhl     /// ```
333a0a4e170SAlice Ryhl     /// use kernel::sync::{Arc, UniqueArc};
334a0a4e170SAlice Ryhl     ///
335a0a4e170SAlice Ryhl     /// let arc = Arc::new(42, GFP_KERNEL)?;
336a0a4e170SAlice Ryhl     /// let another = arc.clone();
337a0a4e170SAlice Ryhl     ///
338a0a4e170SAlice Ryhl     /// let unique_arc = arc.into_unique_or_drop();
339a0a4e170SAlice Ryhl     ///
340a0a4e170SAlice Ryhl     /// // The above conversion should fail since refcount of `arc` is >1.
341a0a4e170SAlice Ryhl     /// assert!(unique_arc.is_none());
342a0a4e170SAlice Ryhl     ///
343a0a4e170SAlice Ryhl     /// # Ok::<(), Error>(())
344a0a4e170SAlice Ryhl     /// ```
into_unique_or_drop(self) -> Option<Pin<UniqueArc<T>>>345a0a4e170SAlice Ryhl     pub fn into_unique_or_drop(self) -> Option<Pin<UniqueArc<T>>> {
346a0a4e170SAlice Ryhl         // We will manually manage the refcount in this method, so we disable the destructor.
347a0a4e170SAlice Ryhl         let me = ManuallyDrop::new(self);
348a0a4e170SAlice Ryhl         // SAFETY: We own a refcount, so the pointer is still valid.
349a0a4e170SAlice Ryhl         let refcount = unsafe { me.ptr.as_ref() }.refcount.get();
350a0a4e170SAlice Ryhl 
351a0a4e170SAlice Ryhl         // If the refcount reaches a non-zero value, then we have destroyed this `Arc` and will
352a0a4e170SAlice Ryhl         // return without further touching the `Arc`. If the refcount reaches zero, then there are
353a0a4e170SAlice Ryhl         // no other arcs, and we can create a `UniqueArc`.
354a0a4e170SAlice Ryhl         //
355a0a4e170SAlice Ryhl         // SAFETY: We own a refcount, so the pointer is not dangling.
356a0a4e170SAlice Ryhl         let is_zero = unsafe { bindings::refcount_dec_and_test(refcount) };
357a0a4e170SAlice Ryhl         if is_zero {
358a0a4e170SAlice Ryhl             // SAFETY: We have exclusive access to the arc, so we can perform unsynchronized
359a0a4e170SAlice Ryhl             // accesses to the refcount.
360a0a4e170SAlice Ryhl             unsafe { core::ptr::write(refcount, bindings::REFCOUNT_INIT(1)) };
361a0a4e170SAlice Ryhl 
362a0a4e170SAlice Ryhl             // INVARIANT: We own the only refcount to this arc, so we may create a `UniqueArc`. We
3639dc04365SWedson Almeida Filho             // must pin the `UniqueArc` because the values was previously in an `Arc`, and they pin
3649dc04365SWedson Almeida Filho             // their values.
3650c7ae432SWedson Almeida Filho             Some(Pin::from(UniqueArc {
3660c7ae432SWedson Almeida Filho                 inner: ManuallyDrop::into_inner(me),
367c27e705cSAlice Ryhl             }))
3680c7ae432SWedson Almeida Filho         } else {
36914686571STamir Duberstein             None
370aa991a2aSTamir Duberstein         }
3710c7ae432SWedson Almeida Filho     }
3720c7ae432SWedson Almeida Filho }
37314686571STamir Duberstein 
374c6340da3STamir Duberstein impl<T: 'static> ForeignOwnable for Arc<T> {
375c6340da3STamir Duberstein     type Borrowed<'a> = ArcBorrow<'a, T>;
37614686571STamir Duberstein     type BorrowedMut<'a> = Self::Borrowed<'a>;
377c6340da3STamir Duberstein 
into_foreign(self) -> *mut crate::ffi::c_void3780c7ae432SWedson Almeida Filho     fn into_foreign(self) -> *mut crate::ffi::c_void {
3790c7ae432SWedson Almeida Filho         ManuallyDrop::new(self).ptr.as_ptr().cast()
3800c7ae432SWedson Almeida Filho     }
381c6340da3STamir Duberstein 
from_foreign(ptr: *mut crate::ffi::c_void) -> Self3820c7ae432SWedson Almeida Filho     unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
383c6b97538STamir Duberstein         // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
384c6b97538STamir Duberstein         // call to `Self::into_foreign`.
385c6b97538STamir Duberstein         let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
386c6b97538STamir Duberstein 
387c6b97538STamir Duberstein         // SAFETY: By the safety requirement of this function, we know that `ptr` came from
388c6b97538STamir Duberstein         // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
389c6b97538STamir Duberstein         // holds a reference count increment that is transferrable to us.
390c6b97538STamir Duberstein         unsafe { Self::from_inner(inner) }
391c6b97538STamir Duberstein     }
392c6b97538STamir Duberstein 
borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T>393c27e705cSAlice Ryhl     unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
394c27e705cSAlice Ryhl         // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
395c27e705cSAlice Ryhl         // call to `Self::into_foreign`.
396c27e705cSAlice Ryhl         let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
397c27e705cSAlice Ryhl 
398c27e705cSAlice Ryhl         // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
3990c7ae432SWedson Almeida Filho         // for the lifetime of the returned value.
4000c7ae432SWedson Almeida Filho         unsafe { ArcBorrow::new(inner) }
4019dc04365SWedson Almeida Filho     }
4029dc04365SWedson Almeida Filho 
borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T>4039dc04365SWedson Almeida Filho     unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
4049dc04365SWedson Almeida Filho         // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety
4059dc04365SWedson Almeida Filho         // requirements for `borrow`.
4069dc04365SWedson Almeida Filho         unsafe { Self::borrow(ptr) }
4079dc04365SWedson Almeida Filho     }
4089dc04365SWedson Almeida Filho }
4099dc04365SWedson Almeida Filho 
4109dc04365SWedson Almeida Filho impl<T: ?Sized> Deref for Arc<T> {
41147329ba1SAlice Ryhl     type Target = T;
41247329ba1SAlice Ryhl 
deref(&self) -> &Self::Target41347329ba1SAlice Ryhl     fn deref(&self) -> &Self::Target {
41447329ba1SAlice Ryhl         // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is
41547329ba1SAlice Ryhl         // safe to dereference it.
41647329ba1SAlice Ryhl         unsafe { &self.ptr.as_ref().data }
4179dc04365SWedson Almeida Filho     }
4189dc04365SWedson Almeida Filho }
4195d385a35STamir Duberstein 
4205d385a35STamir Duberstein impl<T: ?Sized> AsRef<T> for Arc<T> {
as_ref(&self) -> &T4215d385a35STamir Duberstein     fn as_ref(&self) -> &T {
4225d385a35STamir Duberstein         self.deref()
4239dc04365SWedson Almeida Filho     }
4249dc04365SWedson Almeida Filho }
4259dc04365SWedson Almeida Filho 
4265d385a35STamir Duberstein impl<T: ?Sized> Clone for Arc<T> {
clone(&self) -> Self4279dc04365SWedson Almeida Filho     fn clone(&self) -> Self {
4289dc04365SWedson Almeida Filho         // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is
4299dc04365SWedson Almeida Filho         // safe to dereference it.
4309dc04365SWedson Almeida Filho         let refcount = unsafe { self.ptr.as_ref() }.refcount.get();
4319dc04365SWedson Almeida Filho 
4329dc04365SWedson Almeida Filho         // INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero.
4339dc04365SWedson Almeida Filho         // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is
4349dc04365SWedson Almeida Filho         // safe to increment the refcount.
4359dc04365SWedson Almeida Filho         unsafe { bindings::refcount_inc(refcount) };
4369dc04365SWedson Almeida Filho 
4379dc04365SWedson Almeida Filho         // SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`.
4389dc04365SWedson Almeida Filho         unsafe { Self::from_inner(self.ptr) }
4399dc04365SWedson Almeida Filho     }
4409dc04365SWedson Almeida Filho }
4419dc04365SWedson Almeida Filho 
4429dc04365SWedson Almeida Filho impl<T: ?Sized> Drop for Arc<T> {
drop(&mut self)4439dc04365SWedson Almeida Filho     fn drop(&mut self) {
4449dc04365SWedson Almeida Filho         // SAFETY: By the type invariant, there is necessarily a reference to the object. We cannot
4459dc04365SWedson Almeida Filho         // touch `refcount` after it's decremented to a non-zero value because another thread/CPU
4469dc04365SWedson Almeida Filho         // may concurrently decrement it to zero and free it. It is ok to have a raw pointer to
4479dc04365SWedson Almeida Filho         // freed/invalid memory as long as it is never dereferenced.
4488373147cSDanilo Krummrich         let refcount = unsafe { self.ptr.as_ref() }.refcount.get();
4498373147cSDanilo Krummrich 
4509dc04365SWedson Almeida Filho         // INVARIANT: If the refcount reaches zero, there are no other instances of `Arc`, and
4519dc04365SWedson Almeida Filho         // this instance is being dropped, so the broken invariant is not observable.
4529dc04365SWedson Almeida Filho         // SAFETY: Also by the type invariant, we are allowed to decrement the refcount.
45317f67160SWedson Almeida Filho         let is_zero = unsafe { bindings::refcount_dec_and_test(refcount) };
45470e42ebbSWedson Almeida Filho         if is_zero {
45570e42ebbSWedson Almeida Filho             // The count reached zero, we must free the memory.
45670e42ebbSWedson Almeida Filho             //
45770e42ebbSWedson Almeida Filho             // SAFETY: The pointer was initialised from the result of `KBox::leak`.
45870e42ebbSWedson Almeida Filho             unsafe { drop(KBox::from_raw(self.ptr.as_ptr())) };
45970e42ebbSWedson Almeida Filho         }
46070e42ebbSWedson Almeida Filho     }
46170e42ebbSWedson Almeida Filho }
46270e42ebbSWedson Almeida Filho 
46370e42ebbSWedson Almeida Filho impl<T: ?Sized> From<UniqueArc<T>> for Arc<T> {
from(item: UniqueArc<T>) -> Self46470e42ebbSWedson Almeida Filho     fn from(item: UniqueArc<T>) -> Self {
46570e42ebbSWedson Almeida Filho         item.inner
46670e42ebbSWedson Almeida Filho     }
46717f67160SWedson Almeida Filho }
46817f67160SWedson Almeida Filho 
46917f67160SWedson Almeida Filho impl<T: ?Sized> From<Pin<UniqueArc<T>>> for Arc<T> {
from(item: Pin<UniqueArc<T>>) -> Self4704c799d1dSValentin Obst     fn from(item: Pin<UniqueArc<T>>) -> Self {
47117f67160SWedson Almeida Filho         // SAFETY: The type invariants of `Arc` guarantee that the data is pinned.
47217f67160SWedson Almeida Filho         unsafe { Pin::into_inner_unchecked(item).inner }
47317f67160SWedson Almeida Filho     }
4744c799d1dSValentin Obst }
4754c799d1dSValentin Obst 
47617f67160SWedson Almeida Filho /// A borrowed reference to an [`Arc`] instance.
47717f67160SWedson Almeida Filho ///
47817f67160SWedson Almeida Filho /// For cases when one doesn't ever need to increment the refcount on the allocation, it is simpler
47917f67160SWedson Almeida Filho /// to use just `&T`, which we can trivially get from an [`Arc<T>`] instance.
48017f67160SWedson Almeida Filho ///
48117f67160SWedson Almeida Filho /// However, when one may need to increment the refcount, it is preferable to use an `ArcBorrow<T>`
48217f67160SWedson Almeida Filho /// over `&Arc<T>` because the latter results in a double-indirection: a pointer (shared reference)
48317f67160SWedson Almeida Filho /// to a pointer ([`Arc<T>`]) to the object (`T`). An [`ArcBorrow`] eliminates this double
48417f67160SWedson Almeida Filho /// indirection while still allowing one to increment the refcount and getting an [`Arc<T>`] when/if
48517f67160SWedson Almeida Filho /// needed.
486bfa7dff0SMiguel Ojeda ///
48717f67160SWedson Almeida Filho /// # Invariants
48817f67160SWedson Almeida Filho ///
48917f67160SWedson Almeida Filho /// There are no mutable references to the underlying [`Arc`], and it remains valid for the
49017f67160SWedson Almeida Filho /// lifetime of the [`ArcBorrow`] instance.
49117f67160SWedson Almeida Filho ///
49217f67160SWedson Almeida Filho /// # Example
49317f67160SWedson Almeida Filho ///
494cc41670eSWedson Almeida Filho /// ```
49517f67160SWedson Almeida Filho /// use kernel::sync::{Arc, ArcBorrow};
49617f67160SWedson Almeida Filho ///
49717f67160SWedson Almeida Filho /// struct Example;
49817f67160SWedson Almeida Filho ///
499bfa7dff0SMiguel Ojeda /// fn do_something(e: ArcBorrow<'_, Example>) -> Arc<Example> {
50017f67160SWedson Almeida Filho ///     e.into()
50192a655aeSWedson Almeida Filho /// }
50292a655aeSWedson Almeida Filho ///
50392a655aeSWedson Almeida Filho /// let obj = Arc::new(Example, GFP_KERNEL)?;
50492a655aeSWedson Almeida Filho /// let cloned = do_something(obj.as_arc_borrow());
505bfa7dff0SMiguel Ojeda ///
50692a655aeSWedson Almeida Filho /// // Assert that both `obj` and `cloned` point to the same underlying object.
50792a655aeSWedson Almeida Filho /// assert!(core::ptr::eq(&*obj, &*cloned));
50892a655aeSWedson Almeida Filho /// # Ok::<(), Error>(())
50992a655aeSWedson Almeida Filho /// ```
51092a655aeSWedson Almeida Filho ///
51192a655aeSWedson Almeida Filho /// Using `ArcBorrow<T>` as the type of `self`:
51292a655aeSWedson Almeida Filho ///
51392a655aeSWedson Almeida Filho /// ```
51492a655aeSWedson Almeida Filho /// use kernel::sync::{Arc, ArcBorrow};
51592a655aeSWedson Almeida Filho ///
51692a655aeSWedson Almeida Filho /// struct Example {
51792a655aeSWedson Almeida Filho ///     a: u32,
518cc41670eSWedson Almeida Filho ///     b: u32,
51992a655aeSWedson Almeida Filho /// }
520bfa7dff0SMiguel Ojeda ///
52192a655aeSWedson Almeida Filho /// impl Example {
52247cb6bf7SXiangfei Ding ///     fn use_reference(self: ArcBorrow<'_, Self>) {
52347cb6bf7SXiangfei Ding ///         // ...
52417f67160SWedson Almeida Filho ///     }
52517f67160SWedson Almeida Filho /// }
52617f67160SWedson Almeida Filho ///
52717f67160SWedson Almeida Filho /// let obj = Arc::new(Example { a: 10, b: 20 }, GFP_KERNEL)?;
52817f67160SWedson Almeida Filho /// obj.as_arc_borrow().use_reference();
5290748424aSWedson Almeida Filho /// # Ok::<(), Error>(())
5300748424aSWedson Almeida Filho /// ```
53147cb6bf7SXiangfei Ding #[repr(transparent)]
53247cb6bf7SXiangfei Ding #[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, derive(core::marker::CoercePointee))]
5330748424aSWedson Almeida Filho pub struct ArcBorrow<'a, T: ?Sized + 'a> {
5340748424aSWedson Almeida Filho     inner: NonNull<ArcInner<T>>,
5350748424aSWedson Almeida Filho     _p: PhantomData<&'a ()>,
5360748424aSWedson Almeida Filho }
53717f67160SWedson Almeida Filho 
53817f67160SWedson Almeida Filho // This is to allow `ArcBorrow<U>` to be dispatched on when `ArcBorrow<T>` can be coerced into
53917f67160SWedson Almeida Filho // `ArcBorrow<U>`.
54017f67160SWedson Almeida Filho #[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
54117f67160SWedson Almeida Filho impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<ArcBorrow<'_, U>>
54217f67160SWedson Almeida Filho     for ArcBorrow<'_, T>
54317f67160SWedson Almeida Filho {
54417f67160SWedson Almeida Filho }
54517f67160SWedson Almeida Filho 
54617f67160SWedson Almeida Filho impl<T: ?Sized> Clone for ArcBorrow<'_, T> {
clone(&self) -> Self54717f67160SWedson Almeida Filho     fn clone(&self) -> Self {
54817f67160SWedson Almeida Filho         *self
54917f67160SWedson Almeida Filho     }
55017f67160SWedson Almeida Filho }
55117f67160SWedson Almeida Filho 
55217f67160SWedson Almeida Filho impl<T: ?Sized> Copy for ArcBorrow<'_, T> {}
55317f67160SWedson Almeida Filho 
55417f67160SWedson Almeida Filho impl<T: ?Sized> ArcBorrow<'_, T> {
55517f67160SWedson Almeida Filho     /// Creates a new [`ArcBorrow`] instance.
55617f67160SWedson Almeida Filho     ///
55717f67160SWedson Almeida Filho     /// # Safety
55817f67160SWedson Almeida Filho     ///
55917f67160SWedson Almeida Filho     /// Callers must ensure the following for the lifetime of the returned [`ArcBorrow`] instance:
56051f6af86SAlice Ryhl     /// 1. That `inner` remains valid;
56151f6af86SAlice Ryhl     /// 2. That no mutable references to `inner` are created.
new(inner: NonNull<ArcInner<T>>) -> Self56251f6af86SAlice Ryhl     unsafe fn new(inner: NonNull<ArcInner<T>>) -> Self {
56351f6af86SAlice Ryhl         // INVARIANT: The safety requirements guarantee the invariants.
56451f6af86SAlice Ryhl         Self {
56551f6af86SAlice Ryhl             inner,
56651f6af86SAlice Ryhl             _p: PhantomData,
56751f6af86SAlice Ryhl         }
56851f6af86SAlice Ryhl     }
56951f6af86SAlice Ryhl 
57051f6af86SAlice Ryhl     /// Creates an [`ArcBorrow`] to an [`Arc`] that has previously been deconstructed with
57151f6af86SAlice Ryhl     /// [`Arc::into_raw`] or [`Arc::as_ptr`].
57251f6af86SAlice Ryhl     ///
57351f6af86SAlice Ryhl     /// # Safety
57451f6af86SAlice Ryhl     ///
57551f6af86SAlice Ryhl     /// * The provided pointer must originate from a call to [`Arc::into_raw`] or [`Arc::as_ptr`].
57651f6af86SAlice Ryhl     /// * For the duration of the lifetime annotated on this `ArcBorrow`, the reference count must
57751f6af86SAlice Ryhl     ///   not hit zero.
57851f6af86SAlice Ryhl     /// * For the duration of the lifetime annotated on this `ArcBorrow`, there must not be a
57951f6af86SAlice Ryhl     ///   [`UniqueArc`] reference to this value.
from_raw(ptr: *const T) -> Self58051f6af86SAlice Ryhl     pub unsafe fn from_raw(ptr: *const T) -> Self {
58117f67160SWedson Almeida Filho         // SAFETY: The caller promises that this pointer originates from a call to `into_raw` on an
58217f67160SWedson Almeida Filho         // `Arc` that is still valid.
58317f67160SWedson Almeida Filho         let ptr = unsafe { ArcInner::container_of(ptr) };
58417f67160SWedson Almeida Filho 
58517f67160SWedson Almeida Filho         // SAFETY: The caller promises that the value remains valid since the reference count must
58617f67160SWedson Almeida Filho         // not hit zero, and no mutable reference will be created since that would involve a
58717f67160SWedson Almeida Filho         // `UniqueArc`.
58817f67160SWedson Almeida Filho         unsafe { Self::new(ptr) }
58917f67160SWedson Almeida Filho     }
59017f67160SWedson Almeida Filho }
59117f67160SWedson Almeida Filho 
59217f67160SWedson Almeida Filho impl<T: ?Sized> From<ArcBorrow<'_, T>> for Arc<T> {
from(b: ArcBorrow<'_, T>) -> Self59317f67160SWedson Almeida Filho     fn from(b: ArcBorrow<'_, T>) -> Self {
59417f67160SWedson Almeida Filho         // SAFETY: The existence of `b` guarantees that the refcount is non-zero. `ManuallyDrop`
59517f67160SWedson Almeida Filho         // guarantees that `drop` isn't called, so it's ok that the temporary `Arc` doesn't own the
59617f67160SWedson Almeida Filho         // increment.
59717f67160SWedson Almeida Filho         ManuallyDrop::new(unsafe { Arc::from_inner(b.inner) })
59817f67160SWedson Almeida Filho             .deref()
59917f67160SWedson Almeida Filho             .clone()
60017f67160SWedson Almeida Filho     }
60117f67160SWedson Almeida Filho }
60217f67160SWedson Almeida Filho 
60370e42ebbSWedson Almeida Filho impl<T: ?Sized> Deref for ArcBorrow<'_, T> {
60470e42ebbSWedson Almeida Filho     type Target = T;
60570e42ebbSWedson Almeida Filho 
deref(&self) -> &Self::Target60670e42ebbSWedson Almeida Filho     fn deref(&self) -> &Self::Target {
60770e42ebbSWedson Almeida Filho         // SAFETY: By the type invariant, the underlying object is still alive with no mutable
60870e42ebbSWedson Almeida Filho         // references to it, so it is safe to create a shared reference.
60970e42ebbSWedson Almeida Filho         unsafe { &self.inner.as_ref().data }
61070e42ebbSWedson Almeida Filho     }
61170e42ebbSWedson Almeida Filho }
61270e42ebbSWedson Almeida Filho 
61370e42ebbSWedson Almeida Filho /// A refcounted object that is known to have a refcount of 1.
61470e42ebbSWedson Almeida Filho ///
61570e42ebbSWedson Almeida Filho /// It is mutable and can be converted to an [`Arc`] so that it can be shared.
61670e42ebbSWedson Almeida Filho ///
61770e42ebbSWedson Almeida Filho /// # Invariants
61870e42ebbSWedson Almeida Filho ///
61970e42ebbSWedson Almeida Filho /// `inner` always has a reference count of 1.
62070e42ebbSWedson Almeida Filho ///
62170e42ebbSWedson Almeida Filho /// # Examples
62270e42ebbSWedson Almeida Filho ///
62370e42ebbSWedson Almeida Filho /// In the following example, we make changes to the inner object before turning it into an
62470e42ebbSWedson Almeida Filho /// `Arc<Test>` object (after which point, it cannot be mutated directly). Note that `x.into()`
62570e42ebbSWedson Almeida Filho /// cannot fail.
62670e42ebbSWedson Almeida Filho ///
627cc41670eSWedson Almeida Filho /// ```
62870e42ebbSWedson Almeida Filho /// use kernel::sync::{Arc, UniqueArc};
62970e42ebbSWedson Almeida Filho ///
63070e42ebbSWedson Almeida Filho /// struct Example {
63170e42ebbSWedson Almeida Filho ///     a: u32,
63270e42ebbSWedson Almeida Filho ///     b: u32,
63370e42ebbSWedson Almeida Filho /// }
63470e42ebbSWedson Almeida Filho ///
63570e42ebbSWedson Almeida Filho /// fn test() -> Result<Arc<Example>> {
636ebf2b8a7SValentin Obst ///     let mut x = UniqueArc::new(Example { a: 10, b: 20 }, GFP_KERNEL)?;
63770e42ebbSWedson Almeida Filho ///     x.a += 1;
63870e42ebbSWedson Almeida Filho ///     x.b += 1;
63970e42ebbSWedson Almeida Filho ///     Ok(x.into())
64070e42ebbSWedson Almeida Filho /// }
64170e42ebbSWedson Almeida Filho ///
64270e42ebbSWedson Almeida Filho /// # test().unwrap();
64370e42ebbSWedson Almeida Filho /// ```
64470e42ebbSWedson Almeida Filho ///
64570e42ebbSWedson Almeida Filho /// In the following example we first allocate memory for a refcounted `Example` but we don't
64670e42ebbSWedson Almeida Filho /// initialise it on allocation. We do initialise it later with a call to [`UniqueArc::write`],
64770e42ebbSWedson Almeida Filho /// followed by a conversion to `Arc<Example>`. This is particularly useful when allocation happens
64870e42ebbSWedson Almeida Filho /// in one context (e.g., sleepable) and initialisation in another (e.g., atomic):
64970e42ebbSWedson Almeida Filho ///
650cc41670eSWedson Almeida Filho /// ```
65170e42ebbSWedson Almeida Filho /// use kernel::sync::{Arc, UniqueArc};
65270e42ebbSWedson Almeida Filho ///
65370e42ebbSWedson Almeida Filho /// struct Example {
65470e42ebbSWedson Almeida Filho ///     a: u32,
65570e42ebbSWedson Almeida Filho ///     b: u32,
65670e42ebbSWedson Almeida Filho /// }
65770e42ebbSWedson Almeida Filho ///
65870e42ebbSWedson Almeida Filho /// fn test() -> Result<Arc<Example>> {
65970e42ebbSWedson Almeida Filho ///     let x = UniqueArc::new_uninit(GFP_KERNEL)?;
66070e42ebbSWedson Almeida Filho ///     Ok(x.write(Example { a: 10, b: 20 }).into())
66170e42ebbSWedson Almeida Filho /// }
66270e42ebbSWedson Almeida Filho ///
66370e42ebbSWedson Almeida Filho /// # test().unwrap();
66470e42ebbSWedson Almeida Filho /// ```
66570e42ebbSWedson Almeida Filho ///
66670e42ebbSWedson Almeida Filho /// In the last example below, the caller gets a pinned instance of `Example` while converting to
66770e42ebbSWedson Almeida Filho /// `Arc<Example>`; this is useful in scenarios where one needs a pinned reference during
66870e42ebbSWedson Almeida Filho /// initialisation, for example, when initialising fields that are wrapped in locks.
66970e42ebbSWedson Almeida Filho ///
670cc41670eSWedson Almeida Filho /// ```
67170e42ebbSWedson Almeida Filho /// use kernel::sync::{Arc, UniqueArc};
67270e42ebbSWedson Almeida Filho ///
67370e42ebbSWedson Almeida Filho /// struct Example {
67470e42ebbSWedson Almeida Filho ///     a: u32,
67570e42ebbSWedson Almeida Filho ///     b: u32,
67670e42ebbSWedson Almeida Filho /// }
67770e42ebbSWedson Almeida Filho ///
67870e42ebbSWedson Almeida Filho /// fn test() -> Result<Arc<Example>> {
67970e42ebbSWedson Almeida Filho ///     let mut pinned = Pin::from(UniqueArc::new(Example { a: 10, b: 20 }, GFP_KERNEL)?);
68070e42ebbSWedson Almeida Filho ///     // We can modify `pinned` because it is `Unpin`.
68170e42ebbSWedson Almeida Filho ///     pinned.as_mut().a += 1;
682114ca41fSBenno Lossin ///     Ok(pinned.into())
683114ca41fSBenno Lossin /// }
684114ca41fSBenno Lossin ///
685114ca41fSBenno Lossin /// # test().unwrap();
686114ca41fSBenno Lossin /// ```
687114ca41fSBenno Lossin pub struct UniqueArc<T: ?Sized> {
688114ca41fSBenno Lossin     inner: Arc<T>,
689114ca41fSBenno Lossin }
690114ca41fSBenno Lossin 
691114ca41fSBenno Lossin impl<T> InPlaceInit<T> for UniqueArc<T> {
692114ca41fSBenno Lossin     type PinnedSelf = Pin<Self>;
693114ca41fSBenno Lossin 
694114ca41fSBenno Lossin     #[inline]
try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> where E: From<AllocError>,695114ca41fSBenno Lossin     fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
696114ca41fSBenno Lossin     where
697114ca41fSBenno Lossin         E: From<AllocError>,
698114ca41fSBenno Lossin     {
699114ca41fSBenno Lossin         UniqueArc::new_uninit(flags)?.write_pin_init(init)
700114ca41fSBenno Lossin     }
701114ca41fSBenno Lossin 
702114ca41fSBenno Lossin     #[inline]
try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> where E: From<AllocError>,703114ca41fSBenno Lossin     fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
704114ca41fSBenno Lossin     where
705114ca41fSBenno Lossin         E: From<AllocError>,
706114ca41fSBenno Lossin     {
707114ca41fSBenno Lossin         UniqueArc::new_uninit(flags)?.write_init(init)
708114ca41fSBenno Lossin     }
709114ca41fSBenno Lossin }
710114ca41fSBenno Lossin 
711114ca41fSBenno Lossin impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
712114ca41fSBenno Lossin     type Initialized = UniqueArc<T>;
713114ca41fSBenno Lossin 
write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E>714114ca41fSBenno Lossin     fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
715114ca41fSBenno Lossin         let slot = self.as_mut_ptr();
716114ca41fSBenno Lossin         // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
717114ca41fSBenno Lossin         // slot is valid.
718114ca41fSBenno Lossin         unsafe { init.__init(slot)? };
719114ca41fSBenno Lossin         // SAFETY: All fields have been initialized.
720114ca41fSBenno Lossin         Ok(unsafe { self.assume_init() })
721114ca41fSBenno Lossin     }
722114ca41fSBenno Lossin 
write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>723114ca41fSBenno Lossin     fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> {
72470e42ebbSWedson Almeida Filho         let slot = self.as_mut_ptr();
72570e42ebbSWedson Almeida Filho         // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
726cc41670eSWedson Almeida Filho         // slot is valid and will not be moved, because we pin it later.
72770e42ebbSWedson Almeida Filho         unsafe { init.__pinned_init(slot)? };
728ebf2b8a7SValentin Obst         // SAFETY: All fields have been initialized.
729cc41670eSWedson Almeida Filho         Ok(unsafe { self.assume_init() }.into())
73070e42ebbSWedson Almeida Filho     }
73170e42ebbSWedson Almeida Filho }
73270e42ebbSWedson Almeida Filho 
73370e42ebbSWedson Almeida Filho impl<T> UniqueArc<T> {
734c34aa00dSWedson Almeida Filho     /// Tries to allocate a new [`UniqueArc`] instance.
new(value: T, flags: Flags) -> Result<Self, AllocError>735701608bdSBenno Lossin     pub fn new(value: T, flags: Flags) -> Result<Self, AllocError> {
7368373147cSDanilo Krummrich         Ok(Self {
737c34aa00dSWedson Almeida Filho             // INVARIANT: The newly-created object has a refcount of 1.
738701608bdSBenno Lossin             inner: Arc::new(value, flags)?,
739701608bdSBenno Lossin         })
740*dbd5058bSBenno Lossin     }
741c34aa00dSWedson Almeida Filho 
742c34aa00dSWedson Almeida Filho     /// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet.
new_uninit(flags: Flags) -> Result<UniqueArc<MaybeUninit<T>>, AllocError>743c34aa00dSWedson Almeida Filho     pub fn new_uninit(flags: Flags) -> Result<UniqueArc<MaybeUninit<T>>, AllocError> {
744701608bdSBenno Lossin         // INVARIANT: The refcount is initialised to a non-zero value.
745ebf2b8a7SValentin Obst         let inner = KBox::try_init::<AllocError>(
7468373147cSDanilo Krummrich             try_init!(ArcInner {
7478373147cSDanilo Krummrich                 // SAFETY: There are no safety requirements for this FFI call.
74870e42ebbSWedson Almeida Filho                 refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }),
74970e42ebbSWedson Almeida Filho                 data <- pin_init::uninit::<T, AllocError>(),
75070e42ebbSWedson Almeida Filho             }? AllocError),
75170e42ebbSWedson Almeida Filho             flags,
75270e42ebbSWedson Almeida Filho         )?;
75370e42ebbSWedson Almeida Filho         Ok(UniqueArc {
75470e42ebbSWedson Almeida Filho             // INVARIANT: The newly-created object has a refcount of 1.
75570e42ebbSWedson Almeida Filho             // SAFETY: The pointer from the `KBox` is valid.
75631d95c2fSAsahi Lina             inner: unsafe { Arc::from_inner(KBox::leak(inner).into()) },
75731d95c2fSAsahi Lina         })
75831d95c2fSAsahi Lina     }
75931d95c2fSAsahi Lina }
76031d95c2fSAsahi Lina 
76131d95c2fSAsahi Lina impl<T> UniqueArc<MaybeUninit<T>> {
76231d95c2fSAsahi Lina     /// Converts a `UniqueArc<MaybeUninit<T>>` into a `UniqueArc<T>` by writing a value into it.
write(mut self, value: T) -> UniqueArc<T>76331d95c2fSAsahi Lina     pub fn write(mut self, value: T) -> UniqueArc<T> {
76431d95c2fSAsahi Lina         self.deref_mut().write(value);
76531d95c2fSAsahi Lina         // SAFETY: We just wrote the value to be initialized.
76631d95c2fSAsahi Lina         unsafe { self.assume_init() }
76770e42ebbSWedson Almeida Filho     }
76870e42ebbSWedson Almeida Filho 
76970e42ebbSWedson Almeida Filho     /// Unsafely assume that `self` is initialized.
77070e42ebbSWedson Almeida Filho     ///
77170e42ebbSWedson Almeida Filho     /// # Safety
77270e42ebbSWedson Almeida Filho     ///
77370e42ebbSWedson Almeida Filho     /// The caller guarantees that the value behind this pointer has been initialized. It is
7741944caa8SBenno Lossin     /// *immediate* UB to call this when the value is not initialized.
assume_init(self) -> UniqueArc<T>7751944caa8SBenno Lossin     pub unsafe fn assume_init(self) -> UniqueArc<T> {
7761944caa8SBenno Lossin         let inner = ManuallyDrop::new(self).inner.ptr;
7771944caa8SBenno Lossin         UniqueArc {
7781944caa8SBenno Lossin             // SAFETY: The new `Arc` is taking over `ptr` from `self.inner` (which won't be
7791944caa8SBenno Lossin             // dropped). The types are compatible because `MaybeUninit<T>` is compatible with `T`.
7801944caa8SBenno Lossin             inner: unsafe { Arc::from_inner(inner.cast()) },
7811944caa8SBenno Lossin         }
7821944caa8SBenno Lossin     }
7831944caa8SBenno Lossin 
7841944caa8SBenno Lossin     /// Initialize `self` using the given initializer.
init_with<E>(mut self, init: impl Init<T, E>) -> core::result::Result<UniqueArc<T>, E>7851944caa8SBenno Lossin     pub fn init_with<E>(mut self, init: impl Init<T, E>) -> core::result::Result<UniqueArc<T>, E> {
7861944caa8SBenno Lossin         // SAFETY: The supplied pointer is valid for initialization.
7871944caa8SBenno Lossin         match unsafe { init.__init(self.as_mut_ptr()) } {
7881944caa8SBenno Lossin             // SAFETY: Initialization completed successfully.
7891944caa8SBenno Lossin             Ok(()) => Ok(unsafe { self.assume_init() }),
7901944caa8SBenno Lossin             Err(err) => Err(err),
7911944caa8SBenno Lossin         }
7921944caa8SBenno Lossin     }
7931944caa8SBenno Lossin 
7941944caa8SBenno Lossin     /// Pin-initialize `self` using the given pin-initializer.
pin_init_with<E>( mut self, init: impl PinInit<T, E>, ) -> core::result::Result<Pin<UniqueArc<T>>, E>7951944caa8SBenno Lossin     pub fn pin_init_with<E>(
7961944caa8SBenno Lossin         mut self,
7971944caa8SBenno Lossin         init: impl PinInit<T, E>,
79870e42ebbSWedson Almeida Filho     ) -> core::result::Result<Pin<UniqueArc<T>>, E> {
79970e42ebbSWedson Almeida Filho         // SAFETY: The supplied pointer is valid for initialization and we will later pin the value
80070e42ebbSWedson Almeida Filho         // to ensure it does not move.
80170e42ebbSWedson Almeida Filho         match unsafe { init.__pinned_init(self.as_mut_ptr()) } {
80270e42ebbSWedson Almeida Filho             // SAFETY: Initialization completed successfully.
80370e42ebbSWedson Almeida Filho             Ok(()) => Ok(unsafe { self.assume_init() }.into()),
80470e42ebbSWedson Almeida Filho             Err(err) => Err(err),
80570e42ebbSWedson Almeida Filho         }
80670e42ebbSWedson Almeida Filho     }
80770e42ebbSWedson Almeida Filho }
80870e42ebbSWedson Almeida Filho 
80970e42ebbSWedson Almeida Filho impl<T: ?Sized> From<UniqueArc<T>> for Pin<UniqueArc<T>> {
from(obj: UniqueArc<T>) -> Self81070e42ebbSWedson Almeida Filho     fn from(obj: UniqueArc<T>) -> Self {
81170e42ebbSWedson Almeida Filho         // SAFETY: It is not possible to move/replace `T` inside a `Pin<UniqueArc<T>>` (unless `T`
81270e42ebbSWedson Almeida Filho         // is `Unpin`), so it is ok to convert it to `Pin<UniqueArc<T>>`.
81370e42ebbSWedson Almeida Filho         unsafe { Pin::new_unchecked(obj) }
81470e42ebbSWedson Almeida Filho     }
81570e42ebbSWedson Almeida Filho }
81670e42ebbSWedson Almeida Filho 
81770e42ebbSWedson Almeida Filho impl<T: ?Sized> Deref for UniqueArc<T> {
81870e42ebbSWedson Almeida Filho     type Target = T;
81970e42ebbSWedson Almeida Filho 
deref(&self) -> &Self::Target82070e42ebbSWedson Almeida Filho     fn deref(&self) -> &Self::Target {
82170e42ebbSWedson Almeida Filho         self.inner.deref()
82270e42ebbSWedson Almeida Filho     }
82370e42ebbSWedson Almeida Filho }
82400140a83SBoqun Feng 
82500140a83SBoqun Feng impl<T: ?Sized> DerefMut for UniqueArc<T> {
deref_mut(&mut self) -> &mut Self::Target82600140a83SBoqun Feng     fn deref_mut(&mut self) -> &mut Self::Target {
82700140a83SBoqun Feng         // SAFETY: By the `Arc` type invariant, there is necessarily a reference to the object, so
82800140a83SBoqun Feng         // it is safe to dereference it. Additionally, we know there is only one reference when
82900140a83SBoqun Feng         // it's inside a `UniqueArc`, so it is safe to get a mutable reference.
83000140a83SBoqun Feng         unsafe { &mut self.inner.ptr.as_mut().data }
83100140a83SBoqun Feng     }
83200140a83SBoqun Feng }
83300140a83SBoqun Feng 
83400140a83SBoqun Feng impl<T: fmt::Display + ?Sized> fmt::Display for UniqueArc<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result83500140a83SBoqun Feng     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83600140a83SBoqun Feng         fmt::Display::fmt(self.deref(), f)
83700140a83SBoqun Feng     }
83800140a83SBoqun Feng }
83900140a83SBoqun Feng 
84000140a83SBoqun Feng impl<T: fmt::Display + ?Sized> fmt::Display for Arc<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result84100140a83SBoqun Feng     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84200140a83SBoqun Feng         fmt::Display::fmt(self.deref(), f)
84300140a83SBoqun Feng     }
84400140a83SBoqun Feng }
84500140a83SBoqun Feng 
84600140a83SBoqun Feng impl<T: fmt::Debug + ?Sized> fmt::Debug for UniqueArc<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result84700140a83SBoqun Feng     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
848         fmt::Debug::fmt(self.deref(), f)
849     }
850 }
851 
852 impl<T: fmt::Debug + ?Sized> fmt::Debug for Arc<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result853     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
854         fmt::Debug::fmt(self.deref(), f)
855     }
856 }
857