1 // SPDX-License-Identifier: GPL-2.0 2 3 //! A reference-counted pointer. 4 //! 5 //! This module implements a way for users to create reference-counted objects and pointers to 6 //! them. Such a pointer automatically increments and decrements the count, and drops the 7 //! underlying object when it reaches zero. It is also safe to use concurrently from multiple 8 //! threads. 9 //! 10 //! It is different from the standard library's [`Arc`] in a few ways: 11 //! 1. It is backed by the kernel's `refcount_t` type. 12 //! 2. It does not support weak references, which allows it to be half the size. 13 //! 3. It saturates the reference count instead of aborting when it goes over a threshold. 14 //! 4. It does not provide a `get_mut` method, so the ref counted object is pinned. 15 //! 16 //! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html 17 18 use crate::{bindings, error::Result, types::Opaque}; 19 use alloc::boxed::Box; 20 use core::{ 21 marker::{PhantomData, Unsize}, 22 mem::ManuallyDrop, 23 ops::Deref, 24 ptr::NonNull, 25 }; 26 27 /// A reference-counted pointer to an instance of `T`. 28 /// 29 /// The reference count is incremented when new instances of [`Arc`] are created, and decremented 30 /// when they are dropped. When the count reaches zero, the underlying `T` is also dropped. 31 /// 32 /// # Invariants 33 /// 34 /// The reference count on an instance of [`Arc`] is always non-zero. 35 /// The object pointed to by [`Arc`] is always pinned. 36 /// 37 /// # Examples 38 /// 39 /// ``` 40 /// use kernel::sync::Arc; 41 /// 42 /// struct Example { 43 /// a: u32, 44 /// b: u32, 45 /// } 46 /// 47 /// // Create a ref-counted instance of `Example`. 48 /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; 49 /// 50 /// // Get a new pointer to `obj` and increment the refcount. 51 /// let cloned = obj.clone(); 52 /// 53 /// // Assert that both `obj` and `cloned` point to the same underlying object. 54 /// assert!(core::ptr::eq(&*obj, &*cloned)); 55 /// 56 /// // Destroy `obj` and decrement its refcount. 57 /// drop(obj); 58 /// 59 /// // Check that the values are still accessible through `cloned`. 60 /// assert_eq!(cloned.a, 10); 61 /// assert_eq!(cloned.b, 20); 62 /// 63 /// // The refcount drops to zero when `cloned` goes out of scope, and the memory is freed. 64 /// ``` 65 /// 66 /// Using `Arc<T>` as the type of `self`: 67 /// 68 /// ``` 69 /// use kernel::sync::Arc; 70 /// 71 /// struct Example { 72 /// a: u32, 73 /// b: u32, 74 /// } 75 /// 76 /// impl Example { 77 /// fn take_over(self: Arc<Self>) { 78 /// // ... 79 /// } 80 /// 81 /// fn use_reference(self: &Arc<Self>) { 82 /// // ... 83 /// } 84 /// } 85 /// 86 /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; 87 /// obj.use_reference(); 88 /// obj.take_over(); 89 /// ``` 90 /// 91 /// Coercion from `Arc<Example>` to `Arc<dyn MyTrait>`: 92 /// 93 /// ``` 94 /// use kernel::sync::Arc; 95 /// 96 /// trait MyTrait {} 97 /// 98 /// struct Example; 99 /// impl MyTrait for Example {} 100 /// 101 /// // `obj` has type `Arc<Example>`. 102 /// let obj: Arc<Example> = Arc::try_new(Example)?; 103 /// 104 /// // `coerced` has type `Arc<dyn MyTrait>`. 105 /// let coerced: Arc<dyn MyTrait> = obj; 106 /// ``` 107 pub struct Arc<T: ?Sized> { 108 ptr: NonNull<ArcInner<T>>, 109 _p: PhantomData<ArcInner<T>>, 110 } 111 112 #[repr(C)] 113 struct ArcInner<T: ?Sized> { 114 refcount: Opaque<bindings::refcount_t>, 115 data: T, 116 } 117 118 // This is to allow [`Arc`] (and variants) to be used as the type of `self`. 119 impl<T: ?Sized> core::ops::Receiver for Arc<T> {} 120 121 // This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the 122 // dynamically-sized type (DST) `U`. 123 impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {} 124 125 // SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because 126 // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs 127 // `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` directly, for 128 // example, when the reference count reaches zero and `T` is dropped. 129 unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {} 130 131 // SAFETY: It is safe to send `&Arc<T>` to another thread when the underlying `T` is `Sync` for the 132 // same reason as above. `T` needs to be `Send` as well because a thread can clone an `&Arc<T>` 133 // into an `Arc<T>`, which may lead to `T` being accessed by the same reasoning as above. 134 unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {} 135 136 impl<T> Arc<T> { 137 /// Constructs a new reference counted instance of `T`. 138 pub fn try_new(contents: T) -> Result<Self> { 139 // INVARIANT: The refcount is initialised to a non-zero value. 140 let value = ArcInner { 141 // SAFETY: There are no safety requirements for this FFI call. 142 refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), 143 data: contents, 144 }; 145 146 let inner = Box::try_new(value)?; 147 148 // SAFETY: We just created `inner` with a reference count of 1, which is owned by the new 149 // `Arc` object. 150 Ok(unsafe { Self::from_inner(Box::leak(inner).into()) }) 151 } 152 } 153 154 impl<T: ?Sized> Arc<T> { 155 /// Constructs a new [`Arc`] from an existing [`ArcInner`]. 156 /// 157 /// # Safety 158 /// 159 /// The caller must ensure that `inner` points to a valid location and has a non-zero reference 160 /// count, one of which will be owned by the new [`Arc`] instance. 161 unsafe fn from_inner(inner: NonNull<ArcInner<T>>) -> Self { 162 // INVARIANT: By the safety requirements, the invariants hold. 163 Arc { 164 ptr: inner, 165 _p: PhantomData, 166 } 167 } 168 169 /// Returns an [`ArcBorrow`] from the given [`Arc`]. 170 /// 171 /// This is useful when the argument of a function call is an [`ArcBorrow`] (e.g., in a method 172 /// receiver), but we have an [`Arc`] instead. Getting an [`ArcBorrow`] is free when optimised. 173 #[inline] 174 pub fn as_arc_borrow(&self) -> ArcBorrow<'_, T> { 175 // SAFETY: The constraint that the lifetime of the shared reference must outlive that of 176 // the returned `ArcBorrow` ensures that the object remains alive and that no mutable 177 // reference can be created. 178 unsafe { ArcBorrow::new(self.ptr) } 179 } 180 } 181 182 impl<T: ?Sized> Deref for Arc<T> { 183 type Target = T; 184 185 fn deref(&self) -> &Self::Target { 186 // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is 187 // safe to dereference it. 188 unsafe { &self.ptr.as_ref().data } 189 } 190 } 191 192 impl<T: ?Sized> Clone for Arc<T> { 193 fn clone(&self) -> Self { 194 // INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero. 195 // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is 196 // safe to increment the refcount. 197 unsafe { bindings::refcount_inc(self.ptr.as_ref().refcount.get()) }; 198 199 // SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`. 200 unsafe { Self::from_inner(self.ptr) } 201 } 202 } 203 204 impl<T: ?Sized> Drop for Arc<T> { 205 fn drop(&mut self) { 206 // SAFETY: By the type invariant, there is necessarily a reference to the object. We cannot 207 // touch `refcount` after it's decremented to a non-zero value because another thread/CPU 208 // may concurrently decrement it to zero and free it. It is ok to have a raw pointer to 209 // freed/invalid memory as long as it is never dereferenced. 210 let refcount = unsafe { self.ptr.as_ref() }.refcount.get(); 211 212 // INVARIANT: If the refcount reaches zero, there are no other instances of `Arc`, and 213 // this instance is being dropped, so the broken invariant is not observable. 214 // SAFETY: Also by the type invariant, we are allowed to decrement the refcount. 215 let is_zero = unsafe { bindings::refcount_dec_and_test(refcount) }; 216 if is_zero { 217 // The count reached zero, we must free the memory. 218 // 219 // SAFETY: The pointer was initialised from the result of `Box::leak`. 220 unsafe { Box::from_raw(self.ptr.as_ptr()) }; 221 } 222 } 223 } 224 225 /// A borrowed reference to an [`Arc`] instance. 226 /// 227 /// For cases when one doesn't ever need to increment the refcount on the allocation, it is simpler 228 /// to use just `&T`, which we can trivially get from an `Arc<T>` instance. 229 /// 230 /// However, when one may need to increment the refcount, it is preferable to use an `ArcBorrow<T>` 231 /// over `&Arc<T>` because the latter results in a double-indirection: a pointer (shared reference) 232 /// to a pointer (`Arc<T>`) to the object (`T`). An [`ArcBorrow`] eliminates this double 233 /// indirection while still allowing one to increment the refcount and getting an `Arc<T>` when/if 234 /// needed. 235 /// 236 /// # Invariants 237 /// 238 /// There are no mutable references to the underlying [`Arc`], and it remains valid for the 239 /// lifetime of the [`ArcBorrow`] instance. 240 /// 241 /// # Example 242 /// 243 /// ``` 244 /// use crate::sync::{Arc, ArcBorrow}; 245 /// 246 /// struct Example; 247 /// 248 /// fn do_something(e: ArcBorrow<'_, Example>) -> Arc<Example> { 249 /// e.into() 250 /// } 251 /// 252 /// let obj = Arc::try_new(Example)?; 253 /// let cloned = do_something(obj.as_arc_borrow()); 254 /// 255 /// // Assert that both `obj` and `cloned` point to the same underlying object. 256 /// assert!(core::ptr::eq(&*obj, &*cloned)); 257 /// ``` 258 /// 259 /// Using `ArcBorrow<T>` as the type of `self`: 260 /// 261 /// ``` 262 /// use crate::sync::{Arc, ArcBorrow}; 263 /// 264 /// struct Example { 265 /// a: u32, 266 /// b: u32, 267 /// } 268 /// 269 /// impl Example { 270 /// fn use_reference(self: ArcBorrow<'_, Self>) { 271 /// // ... 272 /// } 273 /// } 274 /// 275 /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; 276 /// obj.as_arc_borrow().use_reference(); 277 /// ``` 278 pub struct ArcBorrow<'a, T: ?Sized + 'a> { 279 inner: NonNull<ArcInner<T>>, 280 _p: PhantomData<&'a ()>, 281 } 282 283 // This is to allow [`ArcBorrow`] (and variants) to be used as the type of `self`. 284 impl<T: ?Sized> core::ops::Receiver for ArcBorrow<'_, T> {} 285 286 impl<T: ?Sized> Clone for ArcBorrow<'_, T> { 287 fn clone(&self) -> Self { 288 *self 289 } 290 } 291 292 impl<T: ?Sized> Copy for ArcBorrow<'_, T> {} 293 294 impl<T: ?Sized> ArcBorrow<'_, T> { 295 /// Creates a new [`ArcBorrow`] instance. 296 /// 297 /// # Safety 298 /// 299 /// Callers must ensure the following for the lifetime of the returned [`ArcBorrow`] instance: 300 /// 1. That `inner` remains valid; 301 /// 2. That no mutable references to `inner` are created. 302 unsafe fn new(inner: NonNull<ArcInner<T>>) -> Self { 303 // INVARIANT: The safety requirements guarantee the invariants. 304 Self { 305 inner, 306 _p: PhantomData, 307 } 308 } 309 } 310 311 impl<T: ?Sized> From<ArcBorrow<'_, T>> for Arc<T> { 312 fn from(b: ArcBorrow<'_, T>) -> Self { 313 // SAFETY: The existence of `b` guarantees that the refcount is non-zero. `ManuallyDrop` 314 // guarantees that `drop` isn't called, so it's ok that the temporary `Arc` doesn't own the 315 // increment. 316 ManuallyDrop::new(unsafe { Arc::from_inner(b.inner) }) 317 .deref() 318 .clone() 319 } 320 } 321 322 impl<T: ?Sized> Deref for ArcBorrow<'_, T> { 323 type Target = T; 324 325 fn deref(&self) -> &Self::Target { 326 // SAFETY: By the type invariant, the underlying object is still alive with no mutable 327 // references to it, so it is safe to create a shared reference. 328 unsafe { &self.inner.as_ref().data } 329 } 330 } 331