1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Internal reference counting support. 4 //! 5 //! Many C types already have their own reference counting mechanism (e.g. by storing a 6 //! `refcount_t`). This module provides support for directly using their internal reference count 7 //! from Rust; instead of making users have to use an additional Rust-reference count in the form of 8 //! [`Arc`]. 9 //! 10 //! The smart pointer [`ARef<T>`] acts similarly to [`Arc<T>`] in that it holds a refcount on the 11 //! underlying object, but this refcount is internal to the object. It essentially is a Rust 12 //! implementation of the `get_` and `put_` pattern used in C for reference counting. 13 //! 14 //! To make use of [`ARef<MyType>`], `MyType` needs to implement [`AlwaysRefCounted`]. It is a trait 15 //! for accessing the internal reference count of an object of the `MyType` type. 16 //! 17 //! [`Arc`]: crate::sync::Arc 18 //! [`Arc<T>`]: crate::sync::Arc 19 20 use core::{ 21 marker::PhantomData, 22 mem::ManuallyDrop, 23 ops::Deref, 24 ptr::NonNull, // 25 }; 26 27 use crate::{ 28 prelude::*, 29 types::ForeignOwnable, // 30 }; 31 32 /// Types that are _always_ reference counted. 33 /// 34 /// It allows such types to define their own custom ref increment and decrement functions. 35 /// Additionally, it allows users to convert from a shared reference `&T` to an owned reference 36 /// [`ARef<T>`]. 37 /// 38 /// This is usually implemented by wrappers to existing structures on the C side of the code. For 39 /// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted 40 /// instances of a type. 41 /// 42 /// # Safety 43 /// 44 /// Implementers must ensure that increments to the reference count keep the object alive in memory 45 /// at least until matching decrements are performed. 46 /// 47 /// Implementers must also ensure that all instances are reference-counted. (Otherwise they 48 /// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object 49 /// alive.) 50 pub unsafe trait AlwaysRefCounted { 51 /// Increments the reference count on the object. 52 fn inc_ref(&self); 53 54 /// Decrements the reference count on the object. 55 /// 56 /// Frees the object when the count reaches zero. 57 /// 58 /// # Safety 59 /// 60 /// Callers must ensure that there was a previous matching increment to the reference count, 61 /// and that the object is no longer used after its reference count is decremented (as it may 62 /// result in the object being freed), unless the caller owns another increment on the refcount 63 /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls 64 /// [`AlwaysRefCounted::dec_ref`] once). 65 unsafe fn dec_ref(obj: NonNull<Self>); 66 } 67 68 /// An owned reference to an always-reference-counted object. 69 /// 70 /// The object's reference count is automatically decremented when an instance of [`ARef`] is 71 /// dropped. It is also automatically incremented when a new instance is created via 72 /// [`ARef::clone`]. 73 /// 74 /// # Invariants 75 /// 76 /// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In 77 /// particular, the [`ARef`] instance owns an increment on the underlying object's reference count. 78 pub struct ARef<T: AlwaysRefCounted> { 79 ptr: NonNull<T>, 80 _p: PhantomData<T>, 81 } 82 83 // SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because 84 // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs 85 // `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a 86 // mutable reference, for example, when the reference count reaches zero and `T` is dropped. 87 unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {} 88 89 // SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync` 90 // because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, 91 // it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an 92 // `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for 93 // example, when the reference count reaches zero and `T` is dropped. 94 unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {} 95 96 // Even if `T` is pinned, pointers to `T` can still move. 97 impl<T: AlwaysRefCounted> Unpin for ARef<T> {} 98 99 impl<T: AlwaysRefCounted> ARef<T> { 100 /// Creates a new instance of [`ARef`]. 101 /// 102 /// It takes over an increment of the reference count on the underlying object. 103 /// 104 /// # Safety 105 /// 106 /// Callers must ensure that the reference count was incremented at least once, and that they 107 /// are properly relinquishing one increment. That is, if there is only one increment, callers 108 /// must not use the underlying object anymore -- it is only safe to do so via the newly 109 /// created [`ARef`]. 110 pub unsafe fn from_raw(ptr: NonNull<T>) -> Self { 111 // INVARIANT: The safety requirements guarantee that the new instance now owns the 112 // increment on the refcount. 113 Self { 114 ptr, 115 _p: PhantomData, 116 } 117 } 118 119 /// Consumes the `ARef`, returning a raw pointer. 120 /// 121 /// This function does not change the refcount. After calling this function, the caller is 122 /// responsible for the refcount previously managed by the `ARef`. 123 /// 124 /// # Examples 125 /// 126 /// ``` 127 /// use core::ptr::NonNull; 128 /// use kernel::sync::aref::{ARef, AlwaysRefCounted}; 129 /// 130 /// struct Empty {} 131 /// 132 /// # // SAFETY: TODO. 133 /// unsafe impl AlwaysRefCounted for Empty { 134 /// fn inc_ref(&self) {} 135 /// unsafe fn dec_ref(_obj: NonNull<Self>) {} 136 /// } 137 /// 138 /// let mut data = Empty {}; 139 /// let ptr = NonNull::<Empty>::new(&mut data).unwrap(); 140 /// # // SAFETY: TODO. 141 /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) }; 142 /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref); 143 /// 144 /// assert_eq!(ptr, raw_ptr); 145 /// ``` 146 pub fn into_raw(me: Self) -> NonNull<T> { 147 ManuallyDrop::new(me).ptr 148 } 149 } 150 151 impl<T: AlwaysRefCounted> Clone for ARef<T> { 152 fn clone(&self) -> Self { 153 self.inc_ref(); 154 // SAFETY: We just incremented the refcount above. 155 unsafe { Self::from_raw(self.ptr) } 156 } 157 } 158 159 impl<T: AlwaysRefCounted> Deref for ARef<T> { 160 type Target = T; 161 162 fn deref(&self) -> &Self::Target { 163 // SAFETY: The type invariants guarantee that the object is valid. 164 unsafe { self.ptr.as_ref() } 165 } 166 } 167 168 impl<T: AlwaysRefCounted> From<&T> for ARef<T> { 169 fn from(b: &T) -> Self { 170 b.inc_ref(); 171 // SAFETY: We just incremented the refcount above. 172 unsafe { Self::from_raw(NonNull::from(b)) } 173 } 174 } 175 176 impl<T: AlwaysRefCounted> Drop for ARef<T> { 177 fn drop(&mut self) { 178 // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to 179 // decrement. 180 unsafe { T::dec_ref(self.ptr) }; 181 } 182 } 183 184 impl<T, U> PartialEq<ARef<U>> for ARef<T> 185 where 186 T: AlwaysRefCounted + PartialEq<U>, 187 U: AlwaysRefCounted, 188 { 189 #[inline] 190 fn eq(&self, other: &ARef<U>) -> bool { 191 T::eq(&**self, &**other) 192 } 193 } 194 impl<T: AlwaysRefCounted + Eq> Eq for ARef<T> {} 195 196 // SAFETY: `into_foreign` returns a pointer from `NonNull::as_ptr`, so it's non-null. The 197 // `ARef` invariant guarantees that `ptr` points to a valid `T`, so it's aligned to `T`. 198 unsafe impl<T: AlwaysRefCounted> ForeignOwnable for ARef<T> { 199 const FOREIGN_ALIGN: usize = core::mem::align_of::<T>(); 200 201 type Borrowed<'a> 202 = &'a T 203 where 204 Self: 'a; 205 type BorrowedMut<'a> 206 = &'a T 207 where 208 Self: 'a; 209 210 #[inline] 211 fn into_foreign(self) -> *mut c_void { 212 ARef::into_raw(self).as_ptr().cast() 213 } 214 215 #[inline] 216 unsafe fn from_foreign(ptr: *mut c_void) -> Self { 217 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 218 // call to `Self::into_foreign`. 219 let ptr = unsafe { NonNull::new_unchecked(ptr.cast()) }; 220 221 // SAFETY: `ptr` came from `into_foreign`, which consumed an `ARef` without decrementing 222 // the refcount, so we can transfer the ownership to the new `ARef`. 223 unsafe { ARef::from_raw(ptr) } 224 } 225 226 #[inline] 227 unsafe fn borrow<'a>(ptr: *mut c_void) -> &'a T { 228 // SAFETY: The safety requirements of this method ensure that the object remains alive and 229 // immutable for the duration of 'a. 230 unsafe { &*ptr.cast() } 231 } 232 233 #[inline] 234 unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> &'a T { 235 // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety 236 // requirements for `borrow`. 237 unsafe { <Self as ForeignOwnable>::borrow(ptr) } 238 } 239 } 240 241 impl<T, U> PartialEq<&'_ U> for ARef<T> 242 where 243 T: AlwaysRefCounted + PartialEq<U>, 244 { 245 #[inline] 246 fn eq(&self, other: &&U) -> bool { 247 T::eq(&**self, other) 248 } 249 } 250