1 #![allow(dead_code)] 2 //! 这是一个关于对齐的库,提供了一些对齐的宏和函数、结构体 3 4 use core::{alloc::GlobalAlloc, fmt::Debug, ptr::Unique}; 5 6 use crate::{syscall::SystemError, KERNEL_ALLOCATOR}; 7 8 /// # AlignedBox 9 /// 10 /// 一个用于分配对齐内存的结构体。分配的内存地址符合`ALIGN`的要求。 11 /// 如果类型T的对齐要求大于`ALIGN`,则采用T的对齐要求。 12 /// 13 /// ## 说明 14 /// 15 /// `ALIGN`: 对齐要求,必须是2的幂次方,且不为0,否则编译时报错 16 pub struct AlignedBox<T, const ALIGN: usize> { 17 inner: Unique<T>, 18 } 19 20 impl<T, const ALIGN: usize> AlignedBox<T, ALIGN> { 21 const LAYOUT: core::alloc::Layout = { 22 const fn max(a: usize, b: usize) -> usize { 23 if a > b { 24 a 25 } else { 26 b 27 } 28 } 29 let layout = core::alloc::Layout::from_size_align( 30 core::mem::size_of::<T>(), 31 max(ALIGN, core::mem::align_of::<T>()), 32 ); 33 34 if let Ok(layout) = layout { 35 layout 36 } else { 37 panic!("Check alignment failed at compile time.") 38 } 39 }; 40 41 /// 分配一个新的内存空间,并将其初始化为零。然后返回AlignedBox 42 /// 43 /// # Errors 44 /// 45 /// 如果分配失败,则返回`Err(SystemError::ENOMEM)` 46 #[inline(always)] 47 pub fn new_zeroed() -> Result<Self, SystemError> 48 where 49 T: SafeForZero, 50 { 51 let ptr = unsafe { KERNEL_ALLOCATOR.alloc_zeroed(Self::LAYOUT) }; 52 if ptr.is_null() { 53 return Err(SystemError::ENOMEM); 54 } else { 55 return Ok(AlignedBox { 56 inner: unsafe { Unique::new_unchecked(ptr.cast()) }, 57 }); 58 } 59 } 60 } 61 62 impl<T, const ALIGN: usize> Debug for AlignedBox<T, ALIGN> { 63 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 64 return write!( 65 f, 66 "AlignedBox<{:?}, {:?}>, ptr: {:p}, size: {:}", 67 core::any::type_name::<T>(), 68 core::mem::align_of::<T>(), 69 self.inner.as_ptr(), 70 core::mem::size_of::<T>() 71 ); 72 } 73 } 74 75 impl<T, const ALIGN: usize> Drop for AlignedBox<T, ALIGN> { 76 fn drop(&mut self) { 77 unsafe { 78 // 释放 Unique 智能指针所拥有的内存,并调用类型的析构函数以清理资源 79 core::ptr::drop_in_place(self.inner.as_ptr()); 80 // dealloc memory space 81 KERNEL_ALLOCATOR.dealloc(self.inner.as_ptr().cast(), Self::LAYOUT); 82 } 83 } 84 } 85 86 impl<T, const ALIGN: usize> core::ops::Deref for AlignedBox<T, ALIGN> { 87 type Target = T; 88 89 fn deref(&self) -> &Self::Target { 90 unsafe { &*self.inner.as_ptr() } 91 } 92 } 93 94 impl<T, const ALIGN: usize> core::ops::DerefMut for AlignedBox<T, ALIGN> { 95 fn deref_mut(&mut self) -> &mut Self::Target { 96 unsafe { &mut *self.inner.as_ptr() } 97 } 98 } 99 100 impl<T: Clone + SafeForZero, const ALIGN: usize> Clone for AlignedBox<T, ALIGN> { 101 fn clone(&self) -> Self { 102 let mut new: AlignedBox<T, ALIGN> = 103 Self::new_zeroed().unwrap_or_else(|_| alloc::alloc::handle_alloc_error(Self::LAYOUT)); 104 new.clone_from(self); 105 return new; 106 } 107 } 108 109 /// 一个用于表明某个类型是安全的用于零初始化的 trait 110 /// 111 /// 该 trait 用于表明某个类型是安全的用于零初始化的,即该类型的所有位都可以被初始化为 0 而不会出现未定义行为。 112 pub unsafe trait SafeForZero {} 113 114 unsafe impl<const NUM: usize> SafeForZero for [u8; NUM] {} 115