17b32f508SLoGin #![no_std] 27b32f508SLoGin #![feature(const_refs_to_cell)] 37b32f508SLoGin #![feature(const_size_of_val)] 4840045afSLoGin #![allow(clippy::needless_return)] 57b32f508SLoGin 67b32f508SLoGin extern crate alloc; 77b32f508SLoGin use core::{fmt::Debug, mem::size_of_val}; 87b32f508SLoGin 97b32f508SLoGin use alloc::format; 107b32f508SLoGin use kdepends::{memoffset::offset_of, thingbuf::StaticThingBuf}; 117b32f508SLoGin 127b32f508SLoGin #[repr(C)] 137b32f508SLoGin #[derive(Debug, Copy, Clone, PartialEq, Eq)] 147b32f508SLoGin pub struct AllocatorLog { 157b32f508SLoGin /// 日志的id 167b32f508SLoGin pub id: u64, 177b32f508SLoGin /// 日志类型 187b32f508SLoGin pub type_: AllocatorLogType, 197b32f508SLoGin /// 日志的时间 207b32f508SLoGin pub time: u64, 217b32f508SLoGin 227b32f508SLoGin /// 日志的来源 237b32f508SLoGin pub source: LogSource, 247b32f508SLoGin 257b32f508SLoGin /// 日志的来源pid 267b32f508SLoGin pub pid: Option<usize>, 277b32f508SLoGin 287b32f508SLoGin pub checksum: u64, 297b32f508SLoGin } 307b32f508SLoGin 317b32f508SLoGin impl AllocatorLog { 327b32f508SLoGin /// 创建一个日志 337b32f508SLoGin /// 347b32f508SLoGin /// ## 参数 357b32f508SLoGin /// 367b32f508SLoGin /// - `id`:日志的id 377b32f508SLoGin /// - `type_`:日志类型 387b32f508SLoGin /// - `source`:日志来源 397b32f508SLoGin /// - `pid`:日志来源的pid 407b32f508SLoGin /// - `time`:日志的时间 new( id: u64, type_: AllocatorLogType, source: LogSource, pid: Option<usize>, time: u64, ) -> Self417b32f508SLoGin pub fn new( 427b32f508SLoGin id: u64, 437b32f508SLoGin type_: AllocatorLogType, 447b32f508SLoGin source: LogSource, 457b32f508SLoGin pid: Option<usize>, 467b32f508SLoGin time: u64, 477b32f508SLoGin ) -> Self { 487b32f508SLoGin let mut x = Self { 497b32f508SLoGin id, 507b32f508SLoGin type_, 517b32f508SLoGin time, 527b32f508SLoGin source, 537b32f508SLoGin pid, 547b32f508SLoGin checksum: 0, 557b32f508SLoGin }; 567b32f508SLoGin let checksum = Self::calculate_checksum(&x); 577b32f508SLoGin x.checksum = checksum; 587b32f508SLoGin return x; 597b32f508SLoGin } 607b32f508SLoGin zeroed() -> Self617b32f508SLoGin pub const fn zeroed() -> Self { 627b32f508SLoGin return Self { 637b32f508SLoGin id: 0, 647b32f508SLoGin type_: AllocatorLogType::Undefined, 657b32f508SLoGin time: 0, 667b32f508SLoGin source: LogSource::Undefined, 677b32f508SLoGin pid: None, 687b32f508SLoGin checksum: 0, 697b32f508SLoGin }; 707b32f508SLoGin } 717b32f508SLoGin 727b32f508SLoGin /// 计算日志的校验和 calculate_checksum(value: &Self) -> u64737b32f508SLoGin pub fn calculate_checksum(value: &Self) -> u64 { 747b32f508SLoGin let buf = unsafe { 757b32f508SLoGin core::slice::from_raw_parts( 767b32f508SLoGin value as *const _ as *const u8, 777b32f508SLoGin core::mem::size_of::<Self>() - core::mem::size_of::<u64>(), 787b32f508SLoGin ) 797b32f508SLoGin }; 807b32f508SLoGin let checksum = kdepends::crc::crc64::crc64_be(0, buf); 817b32f508SLoGin return checksum; 827b32f508SLoGin } 837b32f508SLoGin 847b32f508SLoGin /// 验证日志的校验和 validate_checksum(&self) -> bool857b32f508SLoGin pub fn validate_checksum(&self) -> bool { 867b32f508SLoGin let checksum = Self::calculate_checksum(self); 877b32f508SLoGin return checksum == self.checksum; 887b32f508SLoGin } 897b32f508SLoGin 907b32f508SLoGin /// 当前日志是否有效 is_valid(&self) -> bool917b32f508SLoGin pub fn is_valid(&self) -> bool { 92840045afSLoGin if !self.validate_checksum() { 937b32f508SLoGin return false; 947b32f508SLoGin } 957b32f508SLoGin 967b32f508SLoGin if self.id == 0 { 977b32f508SLoGin return false; 987b32f508SLoGin } 997b32f508SLoGin 1007b32f508SLoGin return true; 1017b32f508SLoGin } 1027b32f508SLoGin } 1037b32f508SLoGin 1047b32f508SLoGin impl PartialOrd for AllocatorLog { partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering>1057b32f508SLoGin fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { 106840045afSLoGin Some(self.cmp(other)) 1077b32f508SLoGin } 1087b32f508SLoGin } 1097b32f508SLoGin 1107b32f508SLoGin impl Ord for AllocatorLog { cmp(&self, other: &Self) -> core::cmp::Ordering1117b32f508SLoGin fn cmp(&self, other: &Self) -> core::cmp::Ordering { 1127b32f508SLoGin return self.id.cmp(&other.id); 1137b32f508SLoGin } 1147b32f508SLoGin } 1157b32f508SLoGin 1167b32f508SLoGin /// 内存分配器日志类型 1177b32f508SLoGin #[repr(C)] 1187b32f508SLoGin #[derive(Debug, Copy, Clone, PartialEq, Eq)] 1197b32f508SLoGin pub enum AllocatorLogType { 1207b32f508SLoGin Undefined, 1217b32f508SLoGin Alloc(AllocLogItem), 1227b32f508SLoGin AllocZeroed(AllocLogItem), 1237b32f508SLoGin Free(AllocLogItem), 124a17651b1SMemoryShore LazyAlloc(AllocLogItem), 1257b32f508SLoGin } 1267b32f508SLoGin 1277b32f508SLoGin #[repr(C)] 1287b32f508SLoGin #[derive(Copy, Clone, PartialEq, Eq)] 1297b32f508SLoGin pub struct AllocLogItem { 1307b32f508SLoGin pub layout: core::alloc::Layout, 1317b32f508SLoGin pub vaddr: Option<usize>, 1327b32f508SLoGin pub paddr: Option<usize>, 1337b32f508SLoGin } 1347b32f508SLoGin 1357b32f508SLoGin impl AllocLogItem { new(layout: core::alloc::Layout, vaddr: Option<usize>, paddr: Option<usize>) -> Self1367b32f508SLoGin pub fn new(layout: core::alloc::Layout, vaddr: Option<usize>, paddr: Option<usize>) -> Self { 1377b32f508SLoGin return Self { 1387b32f508SLoGin layout, 1397b32f508SLoGin vaddr, 1407b32f508SLoGin paddr, 1417b32f508SLoGin }; 1427b32f508SLoGin } 1437b32f508SLoGin } 1447b32f508SLoGin 1457b32f508SLoGin impl Debug for AllocLogItem { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result1467b32f508SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 1477b32f508SLoGin f.debug_struct("AllocLogItem") 1487b32f508SLoGin .field("layout", &self.layout) 1497b32f508SLoGin .field( 1507b32f508SLoGin "vaddr", 1517b32f508SLoGin &format_args!("{:#x}", *self.vaddr.as_ref().unwrap_or(&0)), 1527b32f508SLoGin ) 1537b32f508SLoGin .field( 1547b32f508SLoGin "paddr", 1557b32f508SLoGin &format_args!("{:#x}", self.paddr.as_ref().unwrap_or(&0)), 1567b32f508SLoGin ) 1577b32f508SLoGin .finish() 1587b32f508SLoGin } 1597b32f508SLoGin } 1607b32f508SLoGin 1617b32f508SLoGin #[repr(u8)] 1627b32f508SLoGin #[derive(Debug, Copy, Clone, PartialEq, Eq)] 1637b32f508SLoGin pub enum LogSource { 1647b32f508SLoGin Undefined = 0, 1657b32f508SLoGin Bump = 1, 1667b32f508SLoGin Buddy = 2, 1677b32f508SLoGin Slab = 3, 1687b32f508SLoGin } 1697b32f508SLoGin 1707b32f508SLoGin pub struct MMLogCycle; 1717b32f508SLoGin 1727b32f508SLoGin impl MMLogCycle { new() -> Self1737b32f508SLoGin pub const fn new() -> Self { 1747b32f508SLoGin Self {} 1757b32f508SLoGin } 1767b32f508SLoGin } 1777b32f508SLoGin 178*bd70d2d1SLoGin impl Default for MMLogCycle { default() -> Self179*bd70d2d1SLoGin fn default() -> Self { 180*bd70d2d1SLoGin Self::new() 181*bd70d2d1SLoGin } 182*bd70d2d1SLoGin } 183*bd70d2d1SLoGin 1847b32f508SLoGin impl kdepends::thingbuf::Recycle<AllocatorLog> for MMLogCycle { new_element(&self) -> AllocatorLog1857b32f508SLoGin fn new_element(&self) -> AllocatorLog { 1867b32f508SLoGin AllocatorLog::zeroed() 1877b32f508SLoGin } 1887b32f508SLoGin recycle(&self, element: &mut AllocatorLog)1897b32f508SLoGin fn recycle(&self, element: &mut AllocatorLog) { 1907b32f508SLoGin *element = AllocatorLog::zeroed(); 1917b32f508SLoGin } 1927b32f508SLoGin } 1937b32f508SLoGin 1947b32f508SLoGin /// 内存分配器日志通道 1957b32f508SLoGin #[repr(C)] 1967b32f508SLoGin pub struct MMLogChannel<const CAP: usize> { 1977b32f508SLoGin pub magic: u32, 1987b32f508SLoGin /// 日志元素的大小 1997b32f508SLoGin pub element_size: u32, 2007b32f508SLoGin /// 日志通道每个槽的大小(字节) 2017b32f508SLoGin pub slot_size: u32, 2027b32f508SLoGin pub capacity: u64, 2037b32f508SLoGin pub slots_offset: u64, 2047b32f508SLoGin pub buf: StaticThingBuf<AllocatorLog, CAP, MMLogCycle>, 2057b32f508SLoGin } 2067b32f508SLoGin 2077b32f508SLoGin impl<const CAP: usize> Debug for MMLogChannel<CAP> { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result2087b32f508SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 2097b32f508SLoGin f.debug_struct("MMLogChannel") 2107b32f508SLoGin .field("magic", &format!("{:#x}", self.magic)) 2117b32f508SLoGin .field("element_size", &self.element_size) 2127b32f508SLoGin .field("capacity", &self.capacity) 2137b32f508SLoGin .field("slots_offset", &self.slots_offset) 2147b32f508SLoGin .field( 2157b32f508SLoGin "buf", 2167b32f508SLoGin &format!( 2177b32f508SLoGin "StaticThingBuf<AllocatorLog, {}, MMLogCycle>", 2187b32f508SLoGin self.capacity 2197b32f508SLoGin ), 2207b32f508SLoGin ) 2217b32f508SLoGin .finish() 2227b32f508SLoGin } 2237b32f508SLoGin } 2247b32f508SLoGin 2257b32f508SLoGin impl<const CAP: usize> MMLogChannel<CAP> { 2267b32f508SLoGin /// 日志通道的魔数 2277b32f508SLoGin pub const MM_LOG_CHANNEL_MAGIC: u32 = 0x4d4c4348; 2287b32f508SLoGin 2297b32f508SLoGin /// 创建一个大小为`capacity`日志通道 new(capacity: usize) -> Self2307b32f508SLoGin pub const fn new(capacity: usize) -> Self { 2317b32f508SLoGin let buffer = StaticThingBuf::with_recycle(MMLogCycle::new()); 2327b32f508SLoGin assert!(buffer.offset_of_slots() != 0); 2337b32f508SLoGin let slot_total_size = size_of_val(&buffer) - buffer.offset_of_slots(); 2347b32f508SLoGin let slot_size = slot_total_size / capacity; 2357b32f508SLoGin assert!(slot_size != 0); 2367b32f508SLoGin assert!(slot_size > size_of_val(&AllocatorLog::zeroed())); 2377b32f508SLoGin 2387b32f508SLoGin let r = Self { 2397b32f508SLoGin magic: Self::MM_LOG_CHANNEL_MAGIC, 2407b32f508SLoGin element_size: core::mem::size_of::<AllocatorLog>() as u32, 2417b32f508SLoGin capacity: capacity as u64, 2427b32f508SLoGin slot_size: slot_size as u32, 2437b32f508SLoGin slots_offset: (offset_of!(MMLogChannel<CAP>, buf) + buffer.offset_of_slots()) as u64, 2447b32f508SLoGin buf: buffer, 2457b32f508SLoGin }; 2467b32f508SLoGin 2477b32f508SLoGin return r; 2487b32f508SLoGin } 2497b32f508SLoGin } 250