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. 159dc04365SWedson Almeida Filho //! 169dc04365SWedson Almeida Filho //! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html 179dc04365SWedson Almeida Filho 189dc04365SWedson Almeida Filho use crate::{bindings, error::Result, types::Opaque}; 199dc04365SWedson Almeida Filho use alloc::boxed::Box; 20*f75cb6fcSWedson Almeida Filho use core::{ 21*f75cb6fcSWedson Almeida Filho marker::{PhantomData, Unsize}, 22*f75cb6fcSWedson Almeida Filho ops::Deref, 23*f75cb6fcSWedson Almeida Filho ptr::NonNull, 24*f75cb6fcSWedson Almeida Filho }; 259dc04365SWedson Almeida Filho 269dc04365SWedson Almeida Filho /// A reference-counted pointer to an instance of `T`. 279dc04365SWedson Almeida Filho /// 289dc04365SWedson Almeida Filho /// The reference count is incremented when new instances of [`Arc`] are created, and decremented 299dc04365SWedson Almeida Filho /// when they are dropped. When the count reaches zero, the underlying `T` is also dropped. 309dc04365SWedson Almeida Filho /// 319dc04365SWedson Almeida Filho /// # Invariants 329dc04365SWedson Almeida Filho /// 339dc04365SWedson Almeida Filho /// The reference count on an instance of [`Arc`] is always non-zero. 349dc04365SWedson Almeida Filho /// The object pointed to by [`Arc`] is always pinned. 359dc04365SWedson Almeida Filho /// 369dc04365SWedson Almeida Filho /// # Examples 379dc04365SWedson Almeida Filho /// 389dc04365SWedson Almeida Filho /// ``` 399dc04365SWedson Almeida Filho /// use kernel::sync::Arc; 409dc04365SWedson Almeida Filho /// 419dc04365SWedson Almeida Filho /// struct Example { 429dc04365SWedson Almeida Filho /// a: u32, 439dc04365SWedson Almeida Filho /// b: u32, 449dc04365SWedson Almeida Filho /// } 459dc04365SWedson Almeida Filho /// 469dc04365SWedson Almeida Filho /// // Create a ref-counted instance of `Example`. 479dc04365SWedson Almeida Filho /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; 489dc04365SWedson Almeida Filho /// 499dc04365SWedson Almeida Filho /// // Get a new pointer to `obj` and increment the refcount. 509dc04365SWedson Almeida Filho /// let cloned = obj.clone(); 519dc04365SWedson Almeida Filho /// 529dc04365SWedson Almeida Filho /// // Assert that both `obj` and `cloned` point to the same underlying object. 539dc04365SWedson Almeida Filho /// assert!(core::ptr::eq(&*obj, &*cloned)); 549dc04365SWedson Almeida Filho /// 559dc04365SWedson Almeida Filho /// // Destroy `obj` and decrement its refcount. 569dc04365SWedson Almeida Filho /// drop(obj); 579dc04365SWedson Almeida Filho /// 589dc04365SWedson Almeida Filho /// // Check that the values are still accessible through `cloned`. 599dc04365SWedson Almeida Filho /// assert_eq!(cloned.a, 10); 609dc04365SWedson Almeida Filho /// assert_eq!(cloned.b, 20); 619dc04365SWedson Almeida Filho /// 629dc04365SWedson Almeida Filho /// // The refcount drops to zero when `cloned` goes out of scope, and the memory is freed. 639dc04365SWedson Almeida Filho /// ``` 6453528772SWedson Almeida Filho /// 6553528772SWedson Almeida Filho /// Using `Arc<T>` as the type of `self`: 6653528772SWedson Almeida Filho /// 6753528772SWedson Almeida Filho /// ``` 6853528772SWedson Almeida Filho /// use kernel::sync::Arc; 6953528772SWedson Almeida Filho /// 7053528772SWedson Almeida Filho /// struct Example { 7153528772SWedson Almeida Filho /// a: u32, 7253528772SWedson Almeida Filho /// b: u32, 7353528772SWedson Almeida Filho /// } 7453528772SWedson Almeida Filho /// 7553528772SWedson Almeida Filho /// impl Example { 7653528772SWedson Almeida Filho /// fn take_over(self: Arc<Self>) { 7753528772SWedson Almeida Filho /// // ... 7853528772SWedson Almeida Filho /// } 7953528772SWedson Almeida Filho /// 8053528772SWedson Almeida Filho /// fn use_reference(self: &Arc<Self>) { 8153528772SWedson Almeida Filho /// // ... 8253528772SWedson Almeida Filho /// } 8353528772SWedson Almeida Filho /// } 8453528772SWedson Almeida Filho /// 8553528772SWedson Almeida Filho /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; 8653528772SWedson Almeida Filho /// obj.use_reference(); 8753528772SWedson Almeida Filho /// obj.take_over(); 8853528772SWedson Almeida Filho /// ``` 89*f75cb6fcSWedson Almeida Filho /// 90*f75cb6fcSWedson Almeida Filho /// Coercion from `Arc<Example>` to `Arc<dyn MyTrait>`: 91*f75cb6fcSWedson Almeida Filho /// 92*f75cb6fcSWedson Almeida Filho /// ``` 93*f75cb6fcSWedson Almeida Filho /// use kernel::sync::Arc; 94*f75cb6fcSWedson Almeida Filho /// 95*f75cb6fcSWedson Almeida Filho /// trait MyTrait {} 96*f75cb6fcSWedson Almeida Filho /// 97*f75cb6fcSWedson Almeida Filho /// struct Example; 98*f75cb6fcSWedson Almeida Filho /// impl MyTrait for Example {} 99*f75cb6fcSWedson Almeida Filho /// 100*f75cb6fcSWedson Almeida Filho /// // `obj` has type `Arc<Example>`. 101*f75cb6fcSWedson Almeida Filho /// let obj: Arc<Example> = Arc::try_new(Example)?; 102*f75cb6fcSWedson Almeida Filho /// 103*f75cb6fcSWedson Almeida Filho /// // `coerced` has type `Arc<dyn MyTrait>`. 104*f75cb6fcSWedson Almeida Filho /// let coerced: Arc<dyn MyTrait> = obj; 105*f75cb6fcSWedson Almeida Filho /// ``` 1069dc04365SWedson Almeida Filho pub struct Arc<T: ?Sized> { 1079dc04365SWedson Almeida Filho ptr: NonNull<ArcInner<T>>, 1089dc04365SWedson Almeida Filho _p: PhantomData<ArcInner<T>>, 1099dc04365SWedson Almeida Filho } 1109dc04365SWedson Almeida Filho 1119dc04365SWedson Almeida Filho #[repr(C)] 1129dc04365SWedson Almeida Filho struct ArcInner<T: ?Sized> { 1139dc04365SWedson Almeida Filho refcount: Opaque<bindings::refcount_t>, 1149dc04365SWedson Almeida Filho data: T, 1159dc04365SWedson Almeida Filho } 1169dc04365SWedson Almeida Filho 11753528772SWedson Almeida Filho // This is to allow [`Arc`] (and variants) to be used as the type of `self`. 11853528772SWedson Almeida Filho impl<T: ?Sized> core::ops::Receiver for Arc<T> {} 11953528772SWedson Almeida Filho 120*f75cb6fcSWedson Almeida Filho // This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the 121*f75cb6fcSWedson Almeida Filho // dynamically-sized type (DST) `U`. 122*f75cb6fcSWedson Almeida Filho impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {} 123*f75cb6fcSWedson Almeida Filho 1249dc04365SWedson Almeida Filho // SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because 1259dc04365SWedson Almeida Filho // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs 1269dc04365SWedson Almeida Filho // `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` directly, for 1279dc04365SWedson Almeida Filho // example, when the reference count reaches zero and `T` is dropped. 1289dc04365SWedson Almeida Filho unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {} 1299dc04365SWedson Almeida Filho 1309dc04365SWedson Almeida Filho // SAFETY: It is safe to send `&Arc<T>` to another thread when the underlying `T` is `Sync` for the 1319dc04365SWedson Almeida Filho // same reason as above. `T` needs to be `Send` as well because a thread can clone an `&Arc<T>` 1329dc04365SWedson Almeida Filho // into an `Arc<T>`, which may lead to `T` being accessed by the same reasoning as above. 1339dc04365SWedson Almeida Filho unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {} 1349dc04365SWedson Almeida Filho 1359dc04365SWedson Almeida Filho impl<T> Arc<T> { 1369dc04365SWedson Almeida Filho /// Constructs a new reference counted instance of `T`. 1379dc04365SWedson Almeida Filho pub fn try_new(contents: T) -> Result<Self> { 1389dc04365SWedson Almeida Filho // INVARIANT: The refcount is initialised to a non-zero value. 1399dc04365SWedson Almeida Filho let value = ArcInner { 1409dc04365SWedson Almeida Filho // SAFETY: There are no safety requirements for this FFI call. 1419dc04365SWedson Almeida Filho refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), 1429dc04365SWedson Almeida Filho data: contents, 1439dc04365SWedson Almeida Filho }; 1449dc04365SWedson Almeida Filho 1459dc04365SWedson Almeida Filho let inner = Box::try_new(value)?; 1469dc04365SWedson Almeida Filho 1479dc04365SWedson Almeida Filho // SAFETY: We just created `inner` with a reference count of 1, which is owned by the new 1489dc04365SWedson Almeida Filho // `Arc` object. 1499dc04365SWedson Almeida Filho Ok(unsafe { Self::from_inner(Box::leak(inner).into()) }) 1509dc04365SWedson Almeida Filho } 1519dc04365SWedson Almeida Filho } 1529dc04365SWedson Almeida Filho 1539dc04365SWedson Almeida Filho impl<T: ?Sized> Arc<T> { 1549dc04365SWedson Almeida Filho /// Constructs a new [`Arc`] from an existing [`ArcInner`]. 1559dc04365SWedson Almeida Filho /// 1569dc04365SWedson Almeida Filho /// # Safety 1579dc04365SWedson Almeida Filho /// 1589dc04365SWedson Almeida Filho /// The caller must ensure that `inner` points to a valid location and has a non-zero reference 1599dc04365SWedson Almeida Filho /// count, one of which will be owned by the new [`Arc`] instance. 1609dc04365SWedson Almeida Filho unsafe fn from_inner(inner: NonNull<ArcInner<T>>) -> Self { 1619dc04365SWedson Almeida Filho // INVARIANT: By the safety requirements, the invariants hold. 1629dc04365SWedson Almeida Filho Arc { 1639dc04365SWedson Almeida Filho ptr: inner, 1649dc04365SWedson Almeida Filho _p: PhantomData, 1659dc04365SWedson Almeida Filho } 1669dc04365SWedson Almeida Filho } 1679dc04365SWedson Almeida Filho } 1689dc04365SWedson Almeida Filho 1699dc04365SWedson Almeida Filho impl<T: ?Sized> Deref for Arc<T> { 1709dc04365SWedson Almeida Filho type Target = T; 1719dc04365SWedson Almeida Filho 1729dc04365SWedson Almeida Filho fn deref(&self) -> &Self::Target { 1739dc04365SWedson Almeida Filho // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is 1749dc04365SWedson Almeida Filho // safe to dereference it. 1759dc04365SWedson Almeida Filho unsafe { &self.ptr.as_ref().data } 1769dc04365SWedson Almeida Filho } 1779dc04365SWedson Almeida Filho } 1789dc04365SWedson Almeida Filho 1799dc04365SWedson Almeida Filho impl<T: ?Sized> Clone for Arc<T> { 1809dc04365SWedson Almeida Filho fn clone(&self) -> Self { 1819dc04365SWedson Almeida Filho // INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero. 1829dc04365SWedson Almeida Filho // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is 1839dc04365SWedson Almeida Filho // safe to increment the refcount. 1849dc04365SWedson Almeida Filho unsafe { bindings::refcount_inc(self.ptr.as_ref().refcount.get()) }; 1859dc04365SWedson Almeida Filho 1869dc04365SWedson Almeida Filho // SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`. 1879dc04365SWedson Almeida Filho unsafe { Self::from_inner(self.ptr) } 1889dc04365SWedson Almeida Filho } 1899dc04365SWedson Almeida Filho } 1909dc04365SWedson Almeida Filho 1919dc04365SWedson Almeida Filho impl<T: ?Sized> Drop for Arc<T> { 1929dc04365SWedson Almeida Filho fn drop(&mut self) { 1939dc04365SWedson Almeida Filho // SAFETY: By the type invariant, there is necessarily a reference to the object. We cannot 1949dc04365SWedson Almeida Filho // touch `refcount` after it's decremented to a non-zero value because another thread/CPU 1959dc04365SWedson Almeida Filho // may concurrently decrement it to zero and free it. It is ok to have a raw pointer to 1969dc04365SWedson Almeida Filho // freed/invalid memory as long as it is never dereferenced. 1979dc04365SWedson Almeida Filho let refcount = unsafe { self.ptr.as_ref() }.refcount.get(); 1989dc04365SWedson Almeida Filho 1999dc04365SWedson Almeida Filho // INVARIANT: If the refcount reaches zero, there are no other instances of `Arc`, and 2009dc04365SWedson Almeida Filho // this instance is being dropped, so the broken invariant is not observable. 2019dc04365SWedson Almeida Filho // SAFETY: Also by the type invariant, we are allowed to decrement the refcount. 2029dc04365SWedson Almeida Filho let is_zero = unsafe { bindings::refcount_dec_and_test(refcount) }; 2039dc04365SWedson Almeida Filho if is_zero { 2049dc04365SWedson Almeida Filho // The count reached zero, we must free the memory. 2059dc04365SWedson Almeida Filho // 2069dc04365SWedson Almeida Filho // SAFETY: The pointer was initialised from the result of `Box::leak`. 2079dc04365SWedson Almeida Filho unsafe { Box::from_raw(self.ptr.as_ptr()) }; 2089dc04365SWedson Almeida Filho } 2099dc04365SWedson Almeida Filho } 2109dc04365SWedson Almeida Filho } 211