Skip to main content

kernel/sync/
aref.rs

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
20use core::{
21    marker::PhantomData,
22    mem::ManuallyDrop,
23    ops::Deref,
24    ptr::NonNull, //
25};
26
27use 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.)
50pub 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.
78pub 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.
87unsafe 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.
94unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {}
95
96// Even if `T` is pinned, pointers to `T` can still move.
97impl<T: AlwaysRefCounted> Unpin for ARef<T> {}
98
99impl<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
151impl<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
159impl<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
168impl<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
176impl<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
184impl<T, U> PartialEq<ARef<U>> for ARef<T>
185where
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}
194impl<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`.
198unsafe 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
241impl<T, U> PartialEq<&'_ U> for ARef<T>
242where
243    T: AlwaysRefCounted + PartialEq<U>,
244{
245    #[inline]
246    fn eq(&self, other: &&U) -> bool {
247        T::eq(&**self, other)
248    }
249}