mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-15 08:56:47 +00:00
修复内核的clippy检查报错 --------- Co-authored-by: Samuel Dai <947309196@qq.com> Co-authored-by: Donkey Kane <109840258+xiaolin2004@users.noreply.github.com> Co-authored-by: themildwind <107623059+themildwind@users.noreply.github.com> Co-authored-by: GnoCiYeH <heyicong@dragonos.org> Co-authored-by: MemoryShore <105195940+MemoryShore@users.noreply.github.com> Co-authored-by: 曾俊 <110876916+ZZJJWarth@users.noreply.github.com> Co-authored-by: sun5etop <146408999+sun5etop@users.noreply.github.com> Co-authored-by: hmt <114841534+1037827920@users.noreply.github.com> Co-authored-by: laokengwt <143977175+laokengwt@users.noreply.github.com> Co-authored-by: TTaq <103996388+TTaq@users.noreply.github.com> Co-authored-by: Jomo <2512364506@qq.com> Co-authored-by: Samuel Dai <samuka007@qq.com> Co-authored-by: sspphh <112558065+sspphh@users.noreply.github.com>
168 lines
5.0 KiB
Rust
168 lines
5.0 KiB
Rust
#![allow(dead_code)]
|
||
//! 这是一个关于对齐的库,提供了一些对齐的宏和函数、结构体
|
||
|
||
use core::{alloc::GlobalAlloc, fmt::Debug, ptr::Unique};
|
||
|
||
use system_error::SystemError;
|
||
|
||
use crate::{arch::MMArch, mm::MemoryManagementArch, KERNEL_ALLOCATOR};
|
||
|
||
/// # AlignedBox
|
||
///
|
||
/// 一个用于分配对齐内存的结构体。分配的内存地址符合`ALIGN`的要求。
|
||
/// 如果类型T的对齐要求大于`ALIGN`,则采用T的对齐要求。
|
||
///
|
||
/// ## 说明
|
||
///
|
||
/// `ALIGN`: 对齐要求,必须是2的幂次方,且不为0,否则编译时报错
|
||
pub struct AlignedBox<T, const ALIGN: usize> {
|
||
inner: Unique<T>,
|
||
}
|
||
|
||
impl<T, const ALIGN: usize> AlignedBox<T, ALIGN> {
|
||
const LAYOUT: core::alloc::Layout = {
|
||
const fn max(a: usize, b: usize) -> usize {
|
||
if a > b {
|
||
a
|
||
} else {
|
||
b
|
||
}
|
||
}
|
||
let layout = core::alloc::Layout::from_size_align(
|
||
core::mem::size_of::<T>(),
|
||
max(ALIGN, core::mem::align_of::<T>()),
|
||
);
|
||
|
||
if let Ok(layout) = layout {
|
||
layout
|
||
} else {
|
||
panic!("Check alignment failed at compile time.")
|
||
}
|
||
};
|
||
|
||
/// 分配一个新的内存空间,并将其初始化为零。然后返回AlignedBox
|
||
///
|
||
/// # Errors
|
||
///
|
||
/// 如果分配失败,则返回`Err(SystemError::ENOMEM)`
|
||
#[inline(always)]
|
||
pub fn new_zeroed() -> Result<Self, SystemError>
|
||
where
|
||
T: SafeForZero,
|
||
{
|
||
let ptr = unsafe { KERNEL_ALLOCATOR.alloc_zeroed(Self::LAYOUT) };
|
||
if ptr.is_null() {
|
||
return Err(SystemError::ENOMEM);
|
||
} else {
|
||
return Ok(AlignedBox {
|
||
inner: unsafe { Unique::new_unchecked(ptr.cast()) },
|
||
});
|
||
}
|
||
}
|
||
|
||
pub unsafe fn new_unchecked(ptr: *mut T) -> Self {
|
||
return AlignedBox {
|
||
inner: Unique::new_unchecked(ptr),
|
||
};
|
||
}
|
||
}
|
||
|
||
impl<T, const ALIGN: usize> Debug for AlignedBox<T, ALIGN> {
|
||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||
return write!(
|
||
f,
|
||
"AlignedBox<{:?}, {:?}>, ptr: {:p}, size: {:}",
|
||
core::any::type_name::<T>(),
|
||
core::mem::align_of::<T>(),
|
||
self.inner.as_ptr(),
|
||
core::mem::size_of::<T>()
|
||
);
|
||
}
|
||
}
|
||
|
||
impl<T, const ALIGN: usize> Drop for AlignedBox<T, ALIGN> {
|
||
fn drop(&mut self) {
|
||
unsafe {
|
||
// 释放 Unique 智能指针所拥有的内存,并调用类型的析构函数以清理资源
|
||
core::ptr::drop_in_place(self.inner.as_ptr());
|
||
// dealloc memory space
|
||
KERNEL_ALLOCATOR.dealloc(self.inner.as_ptr().cast(), Self::LAYOUT);
|
||
}
|
||
}
|
||
}
|
||
|
||
impl<T, const ALIGN: usize> core::ops::Deref for AlignedBox<T, ALIGN> {
|
||
type Target = T;
|
||
|
||
fn deref(&self) -> &Self::Target {
|
||
unsafe { &*self.inner.as_ptr() }
|
||
}
|
||
}
|
||
|
||
impl<T, const ALIGN: usize> core::ops::DerefMut for AlignedBox<T, ALIGN> {
|
||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||
unsafe { &mut *self.inner.as_ptr() }
|
||
}
|
||
}
|
||
|
||
impl<T: Clone + SafeForZero, const ALIGN: usize> Clone for AlignedBox<T, ALIGN> {
|
||
fn clone(&self) -> Self {
|
||
let mut new: AlignedBox<T, ALIGN> =
|
||
Self::new_zeroed().unwrap_or_else(|_| alloc::alloc::handle_alloc_error(Self::LAYOUT));
|
||
new.clone_from(self);
|
||
return new;
|
||
}
|
||
}
|
||
|
||
/// 一个用于表明某个类型是安全的用于零初始化的 trait
|
||
///
|
||
/// 该 trait 用于表明某个类型是安全的用于零初始化的,即该类型的所有位都可以被初始化为 0 而不会出现未定义行为。
|
||
///
|
||
/// # Safety
|
||
///
|
||
/// 该 trait 是 unsafe 的,因为它要求实现者保证该类型的所有位都可以被初始化为 0 而不会出现未定义行为。
|
||
pub unsafe trait SafeForZero {}
|
||
|
||
unsafe impl<const NUM: usize> SafeForZero for [u8; NUM] {}
|
||
|
||
/// 将给定的地址按照页面大小,向上对齐。
|
||
///
|
||
/// 参数 `addr`:要对齐的地址。
|
||
///
|
||
/// 返回值:对齐后的地址。
|
||
pub const fn page_align_up(addr: usize) -> usize {
|
||
let page_size = MMArch::PAGE_SIZE;
|
||
return (addr + page_size - 1) & (!(page_size - 1));
|
||
}
|
||
|
||
pub const fn page_align_down(addr: usize) -> usize {
|
||
let page_size = MMArch::PAGE_SIZE;
|
||
return addr & (!(page_size - 1));
|
||
}
|
||
|
||
pub const fn align_up(addr: usize, align: usize) -> usize {
|
||
assert!(align != 0 && align.is_power_of_two());
|
||
return (addr + align - 1) & (!(align - 1));
|
||
}
|
||
|
||
pub const fn align_down(addr: usize, align: usize) -> usize {
|
||
assert!(align != 0 && align.is_power_of_two());
|
||
return addr & (!(align - 1));
|
||
}
|
||
|
||
/// ## 检查是否对齐
|
||
///
|
||
/// 检查给定的值是否对齐到给定的对齐要求。
|
||
///
|
||
/// ## 参数
|
||
/// - `value`:要检查的值
|
||
/// - `align`:对齐要求,必须是2的幂次方,且不为0,否则运行时panic
|
||
///
|
||
/// ## 返回值
|
||
///
|
||
/// 如果对齐则返回`true`,否则返回`false`
|
||
pub fn check_aligned(value: usize, align: usize) -> bool {
|
||
assert!(align != 0 && align.is_power_of_two());
|
||
return value & (align - 1) == 0;
|
||
}
|