| 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 |
| 21 | PhantomData, |
| 22 | ManuallyDrop, |
| 23 | Deref, |
| 24 | NonNull, // |
| 25 | ; |
| 26 | |
| 27 | use crate:: |
| 28 | *, |
| 29 | 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 |
| 51 | /// Increments the reference count on the object. |
| 52 | ; |
| 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 ; |
| 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 | |
| 79 | ptr: , |
| 80 | _p: , |
| 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 |
| 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 |
| 95 | |
| 96 | // Even if `T` is pinned, pointers to `T` can still move. |
| 97 | |
| 98 | |
| 99 | |
| 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 |
| 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 | |
| 147 | new.ptr |
| 148 | |
| 149 | |
| 150 | |
| 151 | |
| 152 | |
| 153 | self.inc_ref; |
| 154 | // SAFETY: We just incremented the refcount above. |
| 155 | unsafe |
| 156 | |
| 157 | |
| 158 | |
| 159 | |
| 160 | type Target = T; |
| 161 | |
| 162 | |
| 163 | // SAFETY: The type invariants guarantee that the object is valid. |
| 164 | unsafe |
| 165 | |
| 166 | |
| 167 | |
| 168 | |
| 169 | |
| 170 | b.inc_ref; |
| 171 | // SAFETY: We just incremented the refcount above. |
| 172 | unsafe |
| 173 | |
| 174 | |
| 175 | |
| 176 | |
| 177 | |
| 178 | // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to |
| 179 | // decrement. |
| 180 | unsafe ; |
| 181 | |
| 182 | |
| 183 | |
| 184 | |
| 185 | |
| 186 | T: AlwaysRefCounted + , |
| 187 | U: AlwaysRefCounted, |
| 188 | |
| 189 | |
| 190 | |
| 191 | eq |
| 192 | |
| 193 | |
| 194 | |
| 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 |
| 199 | const FOREIGN_ALIGN: usize = ; |
| 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 | |
| 211 | *mut c_void |
| 212 | into_raw.as_ptr.cast |
| 213 | |
| 214 | |
| 215 | |
| 216 | unsafe |
| 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 ; |
| 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 |
| 224 | |
| 225 | |
| 226 | |
| 227 | unsafe |
| 228 | // SAFETY: The safety requirements of this method ensure that the object remains alive and |
| 229 | // immutable for the duration of 'a. |
| 230 | unsafe |
| 231 | |
| 232 | |
| 233 | |
| 234 | unsafe |
| 235 | // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety |
| 236 | // requirements for `borrow`. |
| 237 | unsafe |
| 238 | |
| 239 | |
| 240 | |
| 241 | |
| 242 | |
| 243 | T: AlwaysRefCounted + , |
| 244 | |
| 245 | |
| 246 | |
| 247 | eq |
| 248 | |
| 249 |