summaryrefslogtreecommitdiff
path: root/rust/kernel/alloc/kbox.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/alloc/kbox.rs')
-rw-r--r--rust/kernel/alloc/kbox.rs66
1 files changed, 54 insertions, 12 deletions
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 9ce414361c2c..b77d32f3a58b 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -15,8 +15,9 @@ use core::pin::Pin;
use core::ptr::NonNull;
use core::result::Result;
-use crate::init::{InPlaceInit, InPlaceWrite, Init, PinInit};
+use crate::init::InPlaceInit;
use crate::types::ForeignOwnable;
+use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption};
/// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`.
///
@@ -99,6 +100,10 @@ pub type VBox<T> = Box<T, super::allocator::Vmalloc>;
/// ```
pub type KVBox<T> = Box<T, super::allocator::KVmalloc>;
+// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee:
+// https://doc.rust-lang.org/stable/std/option/index.html#representation).
+unsafe impl<T, A: Allocator> ZeroableOption for Box<T, A> {}
+
// SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`.
unsafe impl<T, A> Send for Box<T, A>
where
@@ -245,6 +250,12 @@ where
Ok(Self::new(x, flags)?.into())
}
+ /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement
+ /// [`Unpin`], then `x` will be pinned in memory and can't be moved.
+ pub fn into_pin(this: Self) -> Pin<Self> {
+ this.into()
+ }
+
/// Forgets the contents (does not run the destructor), but keeps the allocation.
fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> {
let ptr = Self::into_raw(this);
@@ -354,22 +365,30 @@ where
A: Allocator,
{
type Borrowed<'a> = &'a T;
+ type BorrowedMut<'a> = &'a mut T;
- fn into_foreign(self) -> *const crate::ffi::c_void {
- Box::into_raw(self) as _
+ fn into_foreign(self) -> *mut crate::ffi::c_void {
+ Box::into_raw(self).cast()
}
- unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- unsafe { Box::from_raw(ptr as _) }
+ unsafe { Box::from_raw(ptr.cast()) }
}
- unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {
// SAFETY: The safety requirements of this method ensure that the object remains alive and
// immutable for the duration of 'a.
unsafe { &*ptr.cast() }
}
+
+ unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> &'a mut T {
+ let ptr = ptr.cast();
+ // SAFETY: The safety requirements of this method ensure that the pointer is valid and that
+ // nothing else will access the value for the duration of 'a.
+ unsafe { &mut *ptr }
+ }
}
impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
@@ -377,19 +396,20 @@ where
A: Allocator,
{
type Borrowed<'a> = Pin<&'a T>;
+ type BorrowedMut<'a> = Pin<&'a mut T>;
- fn into_foreign(self) -> *const crate::ffi::c_void {
+ fn into_foreign(self) -> *mut crate::ffi::c_void {
// SAFETY: We are still treating the box as pinned.
- Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _
+ Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
}
- unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
+ unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
// call to `Self::into_foreign`.
- unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) }
+ unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) }
}
- unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
+ unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {
// SAFETY: The safety requirements for this function ensure that the object is still alive,
// so it is safe to dereference the raw pointer.
// The safety requirements of `from_foreign` also ensure that the object remains alive for
@@ -399,6 +419,18 @@ where
// SAFETY: This pointer originates from a `Pin<Box<T>>`.
unsafe { Pin::new_unchecked(r) }
}
+
+ unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a mut T> {
+ let ptr = ptr.cast();
+ // SAFETY: The safety requirements for this function ensure that the object is still alive,
+ // so it is safe to dereference the raw pointer.
+ // The safety requirements of `from_foreign` also ensure that the object remains alive for
+ // the lifetime of the returned value.
+ let r = unsafe { &mut *ptr };
+
+ // SAFETY: This pointer originates from a `Pin<Box<T>>`.
+ unsafe { Pin::new_unchecked(r) }
+ }
}
impl<T, A> Deref for Box<T, A>
@@ -427,13 +459,23 @@ where
}
}
+impl<T, A> fmt::Display for Box<T, A>
+where
+ T: ?Sized + fmt::Display,
+ A: Allocator,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ <T as fmt::Display>::fmt(&**self, f)
+ }
+}
+
impl<T, A> fmt::Debug for Box<T, A>
where
T: ?Sized + fmt::Debug,
A: Allocator,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Debug::fmt(&**self, f)
+ <T as fmt::Debug>::fmt(&**self, f)
}
}