Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200// SPDX-License-Identifier: GPL-2.0
//! Internal reference counting support.//!//! Many C types already have their own reference counting mechanism (e.g. by storing a//! `refcount_t`). This module provides support for directly using their internal reference count//! from Rust; instead of making users have to use an additional Rust-reference count in the form of//! [`Arc`].//!//! The smart pointer [`ARef<T>`] acts similarly to [`Arc<T>`] in that it holds a refcount on the//! underlying object, but this refcount is internal to the object. It essentially is a Rust//! implementation of the `get_` and `put_` pattern used in C for reference counting.//!//! To make use of [`ARef<MyType>`], `MyType` needs to implement [`AlwaysRefCounted`]. It is a trait//! for accessing the internal reference count of an object of the `MyType` type.//!//! [`Arc`]: crate::sync::Arc//! [`Arc<T>`]: crate::sync::Arc
use core::{ marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull, //};
/// Types that are _always_ reference counted.////// It allows such types to define their own custom ref increment and decrement functions./// Additionally, it allows users to convert from a shared reference `&T` to an owned reference/// [`ARef<T>`].////// This is usually implemented by wrappers to existing structures on the C side of the code. For/// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted/// instances of a type.////// # Safety////// Implementers must ensure that increments to the reference count keep the object alive in memory/// at least until matching decrements are performed.////// Implementers must also ensure that all instances are reference-counted. (Otherwise they/// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object/// alive.)pub unsafe trait AlwaysRefCounted { /// Increments the reference count on the object. fn inc_ref(&self);
/// Decrements the reference count on the object. /// /// Frees the object when the count reaches zero. /// /// # Safety /// /// Callers must ensure that there was a previous matching increment to the reference count, /// and that the object is no longer used after its reference count is decremented (as it may /// result in the object being freed), unless the caller owns another increment on the refcount /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls /// [`AlwaysRefCounted::dec_ref`] once). unsafe fn dec_ref(obj: NonNull<Self>);}
/// An owned reference to an always-reference-counted object.////// The object's reference count is automatically decremented when an instance of [`ARef`] is/// dropped. It is also automatically incremented when a new instance is created via/// [`ARef::clone`].////// # Invariants////// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In/// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.pub struct ARef<T: AlwaysRefCounted> { ptr: NonNull<T>, _p: PhantomData<T>,}
// SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs// `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a// mutable reference, for example, when the reference count reaches zero and `T` is dropped.unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {}
// SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`// because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,// it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an// `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for// example, when the reference count reaches zero and `T` is dropped.unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {}
// Even if `T` is pinned, pointers to `T` can still move.impl<T: AlwaysRefCounted> Unpin for ARef<T> {}
impl<T: AlwaysRefCounted> ARef<T> { /// Creates a new instance of [`ARef`]. /// /// It takes over an increment of the reference count on the underlying object. /// /// # Safety /// /// Callers must ensure that the reference count was incremented at least once, and that they /// are properly relinquishing one increment. That is, if there is only one increment, callers /// must not use the underlying object anymore -- it is only safe to do so via the newly /// created [`ARef`]. pub unsafe fn from_raw(ptr: NonNull<T>) -> Self { // INVARIANT: The safety requirements guarantee that the new instance now owns the // increment on the refcount. Self { ptr, _p: PhantomData, } }
/// Consumes the `ARef`, returning a raw pointer. /// /// This function does not change the refcount. After calling this function, the caller is /// responsible for the refcount previously managed by the `ARef`. /// /// # Examples /// /// ``` /// use core::ptr::NonNull; /// use kernel::sync::aref::{ARef, AlwaysRefCounted}; /// /// struct Empty {} /// /// # // SAFETY: TODO. /// unsafe impl AlwaysRefCounted for Empty { /// fn inc_ref(&self) {} /// unsafe fn dec_ref(_obj: NonNull<Self>) {} /// } /// /// let mut data = Empty {}; /// let ptr = NonNull::<Empty>::new(&mut data).unwrap(); /// # // SAFETY: TODO. /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) }; /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref); /// /// assert_eq!(ptr, raw_ptr); /// ``` pub fn into_raw(me: Self) -> NonNull<T> { ManuallyDrop::new(me).ptr }}
impl<T: AlwaysRefCounted> Clone for ARef<T> { fn clone(&self) -> Self { self.inc_ref(); // SAFETY: We just incremented the refcount above. unsafe { Self::from_raw(self.ptr) } }}
impl<T: AlwaysRefCounted> Deref for ARef<T> { type Target = T;
fn deref(&self) -> &Self::Target { // SAFETY: The type invariants guarantee that the object is valid. unsafe { self.ptr.as_ref() } }}
impl<T: AlwaysRefCounted> From<&T> for ARef<T> { fn from(b: &T) -> Self { b.inc_ref(); // SAFETY: We just incremented the refcount above. unsafe { Self::from_raw(NonNull::from(b)) } }}
impl<T: AlwaysRefCounted> Drop for ARef<T> { fn drop(&mut self) { // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to // decrement. unsafe { T::dec_ref(self.ptr) }; }}
impl<T, U> PartialEq<ARef<U>> for ARef<T>where T: AlwaysRefCounted + PartialEq<U>, U: AlwaysRefCounted,{ #[inline] fn eq(&self, other: &ARef<U>) -> bool { T::eq(&**self, &**other) }}impl<T: AlwaysRefCounted + Eq> Eq for ARef<T> {}
impl<T, U> PartialEq<&'_ U> for ARef<T>where T: AlwaysRefCounted + PartialEq<U>,{ #[inline] fn eq(&self, other: &&U) -> bool { T::eq(&**self, other) }}