diff options
Diffstat (limited to 'rust/kernel/alloc')
-rw-r--r-- | rust/kernel/alloc/kbox.rs | 53 | ||||
-rw-r--r-- | rust/kernel/alloc/layout.rs | 19 |
2 files changed, 61 insertions, 11 deletions
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 9ce414361c2c..cb4ebea3b074 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -354,22 +354,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 +385,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 +408,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 +448,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) } } diff --git a/rust/kernel/alloc/layout.rs b/rust/kernel/alloc/layout.rs index 4b3cd7fdc816..93ed514f7cc7 100644 --- a/rust/kernel/alloc/layout.rs +++ b/rust/kernel/alloc/layout.rs @@ -43,6 +43,25 @@ impl<T> ArrayLayout<T> { /// # Errors /// /// When `len * size_of::<T>()` overflows or when `len * size_of::<T>() > isize::MAX`. + /// + /// # Examples + /// + /// ``` + /// # use kernel::alloc::layout::{ArrayLayout, LayoutError}; + /// let layout = ArrayLayout::<i32>::new(15)?; + /// assert_eq!(layout.len(), 15); + /// + /// // Errors because `len * size_of::<T>()` overflows. + /// let layout = ArrayLayout::<i32>::new(isize::MAX as usize); + /// assert!(layout.is_err()); + /// + /// // Errors because `len * size_of::<i32>() > isize::MAX`, + /// // even though `len < isize::MAX`. + /// let layout = ArrayLayout::<i32>::new(isize::MAX as usize / 2); + /// assert!(layout.is_err()); + /// + /// # Ok::<(), Error>(()) + /// ``` pub const fn new(len: usize) -> Result<Self, LayoutError> { match len.checked_mul(core::mem::size_of::<T>()) { Some(size) if size <= ISIZE_MAX => { |