xref: /DragonOS/kernel/crates/klog_types/src/lib.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
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