mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
2eff01ee28
Here is the "big and hairy" char/misc/iio and other small driver subsystem updates for 6.13-rc1. Sorry for doing this at the end of the merge window, conference and holiday travel got in the way on my side (hence the 5am pull request emails...) Loads of things in here, and even a fun merge conflict! - rust misc driver bindings and other rust changes to make misc drivers actually possible. I think this is the tipping point, expect to see way more rust drivers going forward now that these bindings are present. Next merge window hopefully we will have pci and platform drivers working, which will fully enable almost all driver subsystems to start accepting (or at least getting) rust drivers. This is the end result of a lot of work from a lot of people, congrats to all of them for getting this far, you've proved many of us wrong in the best way possible, working code :) - IIO driver updates, too many to list individually, that subsystem keeps growing and growing... - Interconnect driver updates - nvmem driver updates - pwm driver updates - platform_driver::remove() fixups, loads of them - counter driver updates - misc driver updates (keba?) - binder driver updates and fixes - loads of other small char/misc/etc driver updates and additions, full details in the shortlog. Note, there is a semi-hairy rust merge conflict when pulling this. The resolution has been in linux-next for a while and can be seen here: https://lore.kernel.org/all/20241111173459.2646d4af@canb.auug.org.au/ All of these have been in linux-next for a while, with no other reported issues other than that merge conflict. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZ0lGpg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykKHQCgvI4Muu2tpdINBVe24Zc8S3ozg0AAnRNg3F7r ikneftUDYtuviSGU/Rs8 =CW+i -----END PGP SIGNATURE----- Merge tag 'char-misc-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc/IIO/whatever driver subsystem updates from Greg KH: "Here is the 'big and hairy' char/misc/iio and other small driver subsystem updates for 6.13-rc1. Loads of things in here, and even a fun merge conflict! - rust misc driver bindings and other rust changes to make misc drivers actually possible. I think this is the tipping point, expect to see way more rust drivers going forward now that these bindings are present. Next merge window hopefully we will have pci and platform drivers working, which will fully enable almost all driver subsystems to start accepting (or at least getting) rust drivers. This is the end result of a lot of work from a lot of people, congrats to all of them for getting this far, you've proved many of us wrong in the best way possible, working code :) - IIO driver updates, too many to list individually, that subsystem keeps growing and growing... - Interconnect driver updates - nvmem driver updates - pwm driver updates - platform_driver::remove() fixups, loads of them - counter driver updates - misc driver updates (keba?) - binder driver updates and fixes - loads of other small char/misc/etc driver updates and additions, full details in the shortlog. All of these have been in linux-next for a while, with no other reported issues other than that merge conflict" * tag 'char-misc-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (401 commits) mei: vsc: Fix typo "maintstepping" -> "mainstepping" firmware: Switch back to struct platform_driver::remove() misc: isl29020: Fix the wrong format specifier scripts/tags.sh: Don't tag usages of DEFINE_MUTEX fpga: Switch back to struct platform_driver::remove() mei: vsc: Improve error logging in vsc_identify_silicon() mei: vsc: Do not re-enable interrupt from vsc_tp_reset() dt-bindings: spmi: qcom,x1e80100-spmi-pmic-arb: Add SAR2130P compatible dt-bindings: spmi: spmi-mtk-pmif: Add compatible for MT8188 spmi: pmic-arb: fix return path in for_each_available_child_of_node() iio: Move __private marking before struct element priv in struct iio_dev docs: iio: ad7380: add adaq4370-4 and adaq4380-4 iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4 iio: adc: ad7380: use local dev variable to shorten long lines iio: adc: ad7380: fix oversampling formula dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts bus: mhi: host: pci_generic: Use pcim_iomap_region() to request and map MHI BAR bus: mhi: host: Switch trace_mhi_gen_tre fields to native endian misc: atmel-ssc: Use of_property_present() for non-boolean properties misc: keba: Add hardware dependency ...
520 lines
18 KiB
Rust
520 lines
18 KiB
Rust
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
//! Kernel types.
|
|
|
|
use crate::init::{self, PinInit};
|
|
use core::{
|
|
cell::UnsafeCell,
|
|
marker::{PhantomData, PhantomPinned},
|
|
mem::{ManuallyDrop, MaybeUninit},
|
|
ops::{Deref, DerefMut},
|
|
ptr::NonNull,
|
|
};
|
|
|
|
/// Used to transfer ownership to and from foreign (non-Rust) languages.
|
|
///
|
|
/// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
|
|
/// later may be transferred back to Rust by calling [`Self::from_foreign`].
|
|
///
|
|
/// This trait is meant to be used in cases when Rust objects are stored in C objects and
|
|
/// eventually "freed" back to Rust.
|
|
pub trait ForeignOwnable: Sized {
|
|
/// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and
|
|
/// [`ForeignOwnable::from_foreign`].
|
|
type Borrowed<'a>;
|
|
|
|
/// Converts a Rust-owned object to a foreign-owned one.
|
|
///
|
|
/// The foreign representation is a pointer to void. There are no guarantees for this pointer.
|
|
/// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
|
|
/// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
|
|
/// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
|
|
fn into_foreign(self) -> *const crate::ffi::c_void;
|
|
|
|
/// Borrows a foreign-owned object.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
|
|
/// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
|
|
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Self::Borrowed<'a>;
|
|
|
|
/// Converts a foreign-owned object back to a Rust-owned one.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
|
|
/// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
|
|
/// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
|
|
/// this object must have been dropped.
|
|
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self;
|
|
|
|
/// Tries to convert a foreign-owned object back to a Rust-owned one.
|
|
///
|
|
/// A convenience wrapper over [`ForeignOwnable::from_foreign`] that returns [`None`] if `ptr`
|
|
/// is null.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// `ptr` must either be null or satisfy the safety requirements for
|
|
/// [`ForeignOwnable::from_foreign`].
|
|
unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
|
|
if ptr.is_null() {
|
|
None
|
|
} else {
|
|
// SAFETY: Since `ptr` is not null here, then `ptr` satisfies the safety requirements
|
|
// of `from_foreign` given the safety requirements of this function.
|
|
unsafe { Some(Self::from_foreign(ptr)) }
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ForeignOwnable for () {
|
|
type Borrowed<'a> = ();
|
|
|
|
fn into_foreign(self) -> *const crate::ffi::c_void {
|
|
core::ptr::NonNull::dangling().as_ptr()
|
|
}
|
|
|
|
unsafe fn borrow<'a>(_: *const crate::ffi::c_void) -> Self::Borrowed<'a> {}
|
|
|
|
unsafe fn from_foreign(_: *const crate::ffi::c_void) -> Self {}
|
|
}
|
|
|
|
/// Runs a cleanup function/closure when dropped.
|
|
///
|
|
/// The [`ScopeGuard::dismiss`] function prevents the cleanup function from running.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// In the example below, we have multiple exit paths and we want to log regardless of which one is
|
|
/// taken:
|
|
///
|
|
/// ```
|
|
/// # use kernel::types::ScopeGuard;
|
|
/// fn example1(arg: bool) {
|
|
/// let _log = ScopeGuard::new(|| pr_info!("example1 completed\n"));
|
|
///
|
|
/// if arg {
|
|
/// return;
|
|
/// }
|
|
///
|
|
/// pr_info!("Do something...\n");
|
|
/// }
|
|
///
|
|
/// # example1(false);
|
|
/// # example1(true);
|
|
/// ```
|
|
///
|
|
/// In the example below, we want to log the same message on all early exits but a different one on
|
|
/// the main exit path:
|
|
///
|
|
/// ```
|
|
/// # use kernel::types::ScopeGuard;
|
|
/// fn example2(arg: bool) {
|
|
/// let log = ScopeGuard::new(|| pr_info!("example2 returned early\n"));
|
|
///
|
|
/// if arg {
|
|
/// return;
|
|
/// }
|
|
///
|
|
/// // (Other early returns...)
|
|
///
|
|
/// log.dismiss();
|
|
/// pr_info!("example2 no early return\n");
|
|
/// }
|
|
///
|
|
/// # example2(false);
|
|
/// # example2(true);
|
|
/// ```
|
|
///
|
|
/// In the example below, we need a mutable object (the vector) to be accessible within the log
|
|
/// function, so we wrap it in the [`ScopeGuard`]:
|
|
///
|
|
/// ```
|
|
/// # use kernel::types::ScopeGuard;
|
|
/// fn example3(arg: bool) -> Result {
|
|
/// let mut vec =
|
|
/// ScopeGuard::new_with_data(KVec::new(), |v| pr_info!("vec had {} elements\n", v.len()));
|
|
///
|
|
/// vec.push(10u8, GFP_KERNEL)?;
|
|
/// if arg {
|
|
/// return Ok(());
|
|
/// }
|
|
/// vec.push(20u8, GFP_KERNEL)?;
|
|
/// Ok(())
|
|
/// }
|
|
///
|
|
/// # assert_eq!(example3(false), Ok(()));
|
|
/// # assert_eq!(example3(true), Ok(()));
|
|
/// ```
|
|
///
|
|
/// # Invariants
|
|
///
|
|
/// The value stored in the struct is nearly always `Some(_)`, except between
|
|
/// [`ScopeGuard::dismiss`] and [`ScopeGuard::drop`]: in this case, it will be `None` as the value
|
|
/// will have been returned to the caller. Since [`ScopeGuard::dismiss`] consumes the guard,
|
|
/// callers won't be able to use it anymore.
|
|
pub struct ScopeGuard<T, F: FnOnce(T)>(Option<(T, F)>);
|
|
|
|
impl<T, F: FnOnce(T)> ScopeGuard<T, F> {
|
|
/// Creates a new guarded object wrapping the given data and with the given cleanup function.
|
|
pub fn new_with_data(data: T, cleanup_func: F) -> Self {
|
|
// INVARIANT: The struct is being initialised with `Some(_)`.
|
|
Self(Some((data, cleanup_func)))
|
|
}
|
|
|
|
/// Prevents the cleanup function from running and returns the guarded data.
|
|
pub fn dismiss(mut self) -> T {
|
|
// INVARIANT: This is the exception case in the invariant; it is not visible to callers
|
|
// because this function consumes `self`.
|
|
self.0.take().unwrap().0
|
|
}
|
|
}
|
|
|
|
impl ScopeGuard<(), fn(())> {
|
|
/// Creates a new guarded object with the given cleanup function.
|
|
pub fn new(cleanup: impl FnOnce()) -> ScopeGuard<(), impl FnOnce(())> {
|
|
ScopeGuard::new_with_data((), move |()| cleanup())
|
|
}
|
|
}
|
|
|
|
impl<T, F: FnOnce(T)> Deref for ScopeGuard<T, F> {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &T {
|
|
// The type invariants guarantee that `unwrap` will succeed.
|
|
&self.0.as_ref().unwrap().0
|
|
}
|
|
}
|
|
|
|
impl<T, F: FnOnce(T)> DerefMut for ScopeGuard<T, F> {
|
|
fn deref_mut(&mut self) -> &mut T {
|
|
// The type invariants guarantee that `unwrap` will succeed.
|
|
&mut self.0.as_mut().unwrap().0
|
|
}
|
|
}
|
|
|
|
impl<T, F: FnOnce(T)> Drop for ScopeGuard<T, F> {
|
|
fn drop(&mut self) {
|
|
// Run the cleanup function if one is still present.
|
|
if let Some((data, cleanup)) = self.0.take() {
|
|
cleanup(data)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Stores an opaque value.
|
|
///
|
|
/// `Opaque<T>` is meant to be used with FFI objects that are never interpreted by Rust code.
|
|
///
|
|
/// It is used to wrap structs from the C side, like for example `Opaque<bindings::mutex>`.
|
|
/// It gets rid of all the usual assumptions that Rust has for a value:
|
|
///
|
|
/// * The value is allowed to be uninitialized (for example have invalid bit patterns: `3` for a
|
|
/// [`bool`]).
|
|
/// * The value is allowed to be mutated, when a `&Opaque<T>` exists on the Rust side.
|
|
/// * No uniqueness for mutable references: it is fine to have multiple `&mut Opaque<T>` point to
|
|
/// the same value.
|
|
/// * The value is not allowed to be shared with other threads (i.e. it is `!Sync`).
|
|
///
|
|
/// This has to be used for all values that the C side has access to, because it can't be ensured
|
|
/// that the C side is adhering to the usual constraints that Rust needs.
|
|
///
|
|
/// Using `Opaque<T>` allows to continue to use references on the Rust side even for values shared
|
|
/// with C.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # #![expect(unreachable_pub, clippy::disallowed_names)]
|
|
/// use kernel::types::Opaque;
|
|
/// # // Emulate a C struct binding which is from C, maybe uninitialized or not, only the C side
|
|
/// # // knows.
|
|
/// # mod bindings {
|
|
/// # pub struct Foo {
|
|
/// # pub val: u8,
|
|
/// # }
|
|
/// # }
|
|
///
|
|
/// // `foo.val` is assumed to be handled on the C side, so we use `Opaque` to wrap it.
|
|
/// pub struct Foo {
|
|
/// foo: Opaque<bindings::Foo>,
|
|
/// }
|
|
///
|
|
/// impl Foo {
|
|
/// pub fn get_val(&self) -> u8 {
|
|
/// let ptr = Opaque::get(&self.foo);
|
|
///
|
|
/// // SAFETY: `Self` is valid from C side.
|
|
/// unsafe { (*ptr).val }
|
|
/// }
|
|
/// }
|
|
///
|
|
/// // Create an instance of `Foo` with the `Opaque` wrapper.
|
|
/// let foo = Foo {
|
|
/// foo: Opaque::new(bindings::Foo { val: 0xdb }),
|
|
/// };
|
|
///
|
|
/// assert_eq!(foo.get_val(), 0xdb);
|
|
/// ```
|
|
#[repr(transparent)]
|
|
pub struct Opaque<T> {
|
|
value: UnsafeCell<MaybeUninit<T>>,
|
|
_pin: PhantomPinned,
|
|
}
|
|
|
|
impl<T> Opaque<T> {
|
|
/// Creates a new opaque value.
|
|
pub const fn new(value: T) -> Self {
|
|
Self {
|
|
value: UnsafeCell::new(MaybeUninit::new(value)),
|
|
_pin: PhantomPinned,
|
|
}
|
|
}
|
|
|
|
/// Creates an uninitialised value.
|
|
pub const fn uninit() -> Self {
|
|
Self {
|
|
value: UnsafeCell::new(MaybeUninit::uninit()),
|
|
_pin: PhantomPinned,
|
|
}
|
|
}
|
|
|
|
/// Creates a pin-initializer from the given initializer closure.
|
|
///
|
|
/// The returned initializer calls the given closure with the pointer to the inner `T` of this
|
|
/// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it.
|
|
///
|
|
/// This function is safe, because the `T` inside of an `Opaque` is allowed to be
|
|
/// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs
|
|
/// to verify at that point that the inner value is valid.
|
|
pub fn ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit<Self> {
|
|
// SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully
|
|
// initialize the `T`.
|
|
unsafe {
|
|
init::pin_init_from_closure::<_, ::core::convert::Infallible>(move |slot| {
|
|
init_func(Self::raw_get(slot));
|
|
Ok(())
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Creates a fallible pin-initializer from the given initializer closure.
|
|
///
|
|
/// The returned initializer calls the given closure with the pointer to the inner `T` of this
|
|
/// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it.
|
|
///
|
|
/// This function is safe, because the `T` inside of an `Opaque` is allowed to be
|
|
/// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs
|
|
/// to verify at that point that the inner value is valid.
|
|
pub fn try_ffi_init<E>(
|
|
init_func: impl FnOnce(*mut T) -> Result<(), E>,
|
|
) -> impl PinInit<Self, E> {
|
|
// SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully
|
|
// initialize the `T`.
|
|
unsafe { init::pin_init_from_closure::<_, E>(move |slot| init_func(Self::raw_get(slot))) }
|
|
}
|
|
|
|
/// Returns a raw pointer to the opaque data.
|
|
pub const fn get(&self) -> *mut T {
|
|
UnsafeCell::get(&self.value).cast::<T>()
|
|
}
|
|
|
|
/// Gets the value behind `this`.
|
|
///
|
|
/// This function is useful to get access to the value without creating intermediate
|
|
/// references.
|
|
pub const fn raw_get(this: *const Self) -> *mut T {
|
|
UnsafeCell::raw_get(this.cast::<UnsafeCell<MaybeUninit<T>>>()).cast::<T>()
|
|
}
|
|
}
|
|
|
|
/// 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> {}
|
|
|
|
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::types::{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 as *mut _).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) };
|
|
}
|
|
}
|
|
|
|
/// A sum type that always holds either a value of type `L` or `R`.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use kernel::types::Either;
|
|
///
|
|
/// let left_value: Either<i32, &str> = Either::Left(7);
|
|
/// let right_value: Either<i32, &str> = Either::Right("right value");
|
|
/// ```
|
|
pub enum Either<L, R> {
|
|
/// Constructs an instance of [`Either`] containing a value of type `L`.
|
|
Left(L),
|
|
|
|
/// Constructs an instance of [`Either`] containing a value of type `R`.
|
|
Right(R),
|
|
}
|
|
|
|
/// Zero-sized type to mark types not [`Send`].
|
|
///
|
|
/// Add this type as a field to your struct if your type should not be sent to a different task.
|
|
/// Since [`Send`] is an auto trait, adding a single field that is `!Send` will ensure that the
|
|
/// whole type is `!Send`.
|
|
///
|
|
/// If a type is `!Send` it is impossible to give control over an instance of the type to another
|
|
/// task. This is useful to include in types that store or reference task-local information. A file
|
|
/// descriptor is an example of such task-local information.
|
|
///
|
|
/// This type also makes the type `!Sync`, which prevents immutable access to the value from
|
|
/// several threads in parallel.
|
|
pub type NotThreadSafe = PhantomData<*mut ()>;
|
|
|
|
/// Used to construct instances of type [`NotThreadSafe`] similar to how `PhantomData` is
|
|
/// constructed.
|
|
///
|
|
/// [`NotThreadSafe`]: type@NotThreadSafe
|
|
#[allow(non_upper_case_globals)]
|
|
pub const NotThreadSafe: NotThreadSafe = PhantomData;
|