1bb24249fSLoGin #![allow(dead_code)] 2bb24249fSLoGin //! 这是一个关于对齐的库,提供了一些对齐的宏和函数、结构体 3bb24249fSLoGin 4bb24249fSLoGin use core::{alloc::GlobalAlloc, fmt::Debug, ptr::Unique}; 5bb24249fSLoGin 640fe15e0SLoGin use crate::{arch::MMArch, mm::MemoryManagementArch, syscall::SystemError, KERNEL_ALLOCATOR}; 7bb24249fSLoGin 8bb24249fSLoGin /// # AlignedBox 9bb24249fSLoGin /// 10bb24249fSLoGin /// 一个用于分配对齐内存的结构体。分配的内存地址符合`ALIGN`的要求。 11bb24249fSLoGin /// 如果类型T的对齐要求大于`ALIGN`,则采用T的对齐要求。 12bb24249fSLoGin /// 13bb24249fSLoGin /// ## 说明 14bb24249fSLoGin /// 15bb24249fSLoGin /// `ALIGN`: 对齐要求,必须是2的幂次方,且不为0,否则编译时报错 16bb24249fSLoGin pub struct AlignedBox<T, const ALIGN: usize> { 17bb24249fSLoGin inner: Unique<T>, 18bb24249fSLoGin } 19bb24249fSLoGin 20bb24249fSLoGin impl<T, const ALIGN: usize> AlignedBox<T, ALIGN> { 21bb24249fSLoGin const LAYOUT: core::alloc::Layout = { 22bb24249fSLoGin const fn max(a: usize, b: usize) -> usize { 23bb24249fSLoGin if a > b { 24bb24249fSLoGin a 25bb24249fSLoGin } else { 26bb24249fSLoGin b 27bb24249fSLoGin } 28bb24249fSLoGin } 29bb24249fSLoGin let layout = core::alloc::Layout::from_size_align( 30bb24249fSLoGin core::mem::size_of::<T>(), 31bb24249fSLoGin max(ALIGN, core::mem::align_of::<T>()), 32bb24249fSLoGin ); 33bb24249fSLoGin 34bb24249fSLoGin if let Ok(layout) = layout { 35bb24249fSLoGin layout 36bb24249fSLoGin } else { 37bb24249fSLoGin panic!("Check alignment failed at compile time.") 38bb24249fSLoGin } 39bb24249fSLoGin }; 40bb24249fSLoGin 41bb24249fSLoGin /// 分配一个新的内存空间,并将其初始化为零。然后返回AlignedBox 42bb24249fSLoGin /// 43bb24249fSLoGin /// # Errors 44bb24249fSLoGin /// 45bb24249fSLoGin /// 如果分配失败,则返回`Err(SystemError::ENOMEM)` 46bb24249fSLoGin #[inline(always)] 47bb24249fSLoGin pub fn new_zeroed() -> Result<Self, SystemError> 48bb24249fSLoGin where 49bb24249fSLoGin T: SafeForZero, 50bb24249fSLoGin { 51bb24249fSLoGin let ptr = unsafe { KERNEL_ALLOCATOR.alloc_zeroed(Self::LAYOUT) }; 52bb24249fSLoGin if ptr.is_null() { 53bb24249fSLoGin return Err(SystemError::ENOMEM); 54bb24249fSLoGin } else { 55bb24249fSLoGin return Ok(AlignedBox { 56bb24249fSLoGin inner: unsafe { Unique::new_unchecked(ptr.cast()) }, 57bb24249fSLoGin }); 58bb24249fSLoGin } 59bb24249fSLoGin } 601496ba7bSLoGin 611496ba7bSLoGin pub unsafe fn new_unchecked(ptr: *mut T) -> Self { 621496ba7bSLoGin return AlignedBox { 631496ba7bSLoGin inner: Unique::new_unchecked(ptr), 641496ba7bSLoGin }; 651496ba7bSLoGin } 66bb24249fSLoGin } 67bb24249fSLoGin 68bb24249fSLoGin impl<T, const ALIGN: usize> Debug for AlignedBox<T, ALIGN> { 69bb24249fSLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 70bb24249fSLoGin return write!( 71bb24249fSLoGin f, 72bb24249fSLoGin "AlignedBox<{:?}, {:?}>, ptr: {:p}, size: {:}", 73bb24249fSLoGin core::any::type_name::<T>(), 74bb24249fSLoGin core::mem::align_of::<T>(), 75bb24249fSLoGin self.inner.as_ptr(), 76bb24249fSLoGin core::mem::size_of::<T>() 77bb24249fSLoGin ); 78bb24249fSLoGin } 79bb24249fSLoGin } 80bb24249fSLoGin 81bb24249fSLoGin impl<T, const ALIGN: usize> Drop for AlignedBox<T, ALIGN> { 82bb24249fSLoGin fn drop(&mut self) { 83bb24249fSLoGin unsafe { 84bb24249fSLoGin // 释放 Unique 智能指针所拥有的内存,并调用类型的析构函数以清理资源 85bb24249fSLoGin core::ptr::drop_in_place(self.inner.as_ptr()); 86bb24249fSLoGin // dealloc memory space 87bb24249fSLoGin KERNEL_ALLOCATOR.dealloc(self.inner.as_ptr().cast(), Self::LAYOUT); 88bb24249fSLoGin } 89bb24249fSLoGin } 90bb24249fSLoGin } 91bb24249fSLoGin 92bb24249fSLoGin impl<T, const ALIGN: usize> core::ops::Deref for AlignedBox<T, ALIGN> { 93bb24249fSLoGin type Target = T; 94bb24249fSLoGin 95bb24249fSLoGin fn deref(&self) -> &Self::Target { 96bb24249fSLoGin unsafe { &*self.inner.as_ptr() } 97bb24249fSLoGin } 98bb24249fSLoGin } 99bb24249fSLoGin 100bb24249fSLoGin impl<T, const ALIGN: usize> core::ops::DerefMut for AlignedBox<T, ALIGN> { 101bb24249fSLoGin fn deref_mut(&mut self) -> &mut Self::Target { 102bb24249fSLoGin unsafe { &mut *self.inner.as_ptr() } 103bb24249fSLoGin } 104bb24249fSLoGin } 105bb24249fSLoGin 106bb24249fSLoGin impl<T: Clone + SafeForZero, const ALIGN: usize> Clone for AlignedBox<T, ALIGN> { 107bb24249fSLoGin fn clone(&self) -> Self { 108bb24249fSLoGin let mut new: AlignedBox<T, ALIGN> = 109bb24249fSLoGin Self::new_zeroed().unwrap_or_else(|_| alloc::alloc::handle_alloc_error(Self::LAYOUT)); 110bb24249fSLoGin new.clone_from(self); 111bb24249fSLoGin return new; 112bb24249fSLoGin } 113bb24249fSLoGin } 114bb24249fSLoGin 115bb24249fSLoGin /// 一个用于表明某个类型是安全的用于零初始化的 trait 116bb24249fSLoGin /// 117bb24249fSLoGin /// 该 trait 用于表明某个类型是安全的用于零初始化的,即该类型的所有位都可以被初始化为 0 而不会出现未定义行为。 118bb24249fSLoGin pub unsafe trait SafeForZero {} 119bb24249fSLoGin 120bb24249fSLoGin unsafe impl<const NUM: usize> SafeForZero for [u8; NUM] {} 12140fe15e0SLoGin 12240fe15e0SLoGin /// 将给定的地址按照页面大小,向上对齐。 12340fe15e0SLoGin /// 12440fe15e0SLoGin /// 参数 `addr`:要对齐的地址。 12540fe15e0SLoGin /// 12640fe15e0SLoGin /// 返回值:对齐后的地址。 12740fe15e0SLoGin pub fn page_align_up(addr: usize) -> usize { 12840fe15e0SLoGin let page_size = MMArch::PAGE_SIZE; 12940fe15e0SLoGin return (addr + page_size - 1) & (!(page_size - 1)); 13040fe15e0SLoGin } 13140fe15e0SLoGin 132*7ae679ddSLoGin pub fn page_align_down(addr: usize) -> usize { 133*7ae679ddSLoGin let page_size = MMArch::PAGE_SIZE; 134*7ae679ddSLoGin return addr & (!(page_size - 1)); 135*7ae679ddSLoGin } 136*7ae679ddSLoGin 13740fe15e0SLoGin /// ## 检查是否对齐 13840fe15e0SLoGin /// 13940fe15e0SLoGin /// 检查给定的值是否对齐到给定的对齐要求。 14040fe15e0SLoGin /// 14140fe15e0SLoGin /// ## 参数 14240fe15e0SLoGin /// - `value`:要检查的值 14340fe15e0SLoGin /// - `align`:对齐要求,必须是2的幂次方,且不为0,否则运行时panic 14440fe15e0SLoGin /// 14540fe15e0SLoGin /// ## 返回值 14640fe15e0SLoGin /// 14740fe15e0SLoGin /// 如果对齐则返回`true`,否则返回`false` 14840fe15e0SLoGin pub fn check_aligned(value: usize, align: usize) -> bool { 14940fe15e0SLoGin assert!(align != 0 && align.is_power_of_two()); 15040fe15e0SLoGin return value & (align - 1) == 0; 15140fe15e0SLoGin } 152