1 extern crate klog_types; 2 3 use core::intrinsics::unlikely; 4 5 use klog_types::{AllocatorLog, AllocatorLogType, LogSource, MMLogChannel}; 6 7 use crate::{ 8 arch::CurrentTimeArch, 9 process::{Pid, ProcessManager}, 10 time::TimeArch, 11 }; 12 13 /// 全局的内存分配器日志通道 14 /// 15 /// 标记为`no_mangle`是为了让调试器能够找到这个变量 16 #[no_mangle] 17 static __MM_ALLOCATOR_LOG_CHANNEL: MMLogChannel<{ MMDebugLogManager::MAX_ALLOC_LOG_NUM }> = 18 MMLogChannel::new(MMDebugLogManager::MAX_ALLOC_LOG_NUM); 19 20 /// 全局的内存分配器日志id分配器 21 /// 22 /// id从1开始, 因为0是无效的id 23 static __MM_DEBUG_LOG_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX); 24 25 /// 记录内存分配器的日志 26 /// 27 /// ## 参数 28 /// 29 /// - `log_type`:日志类型 30 /// - `source`:日志来源 31 pub fn mm_debug_log(log_type: AllocatorLogType, source: LogSource) { 32 let pid = if unlikely(!ProcessManager::initialized()) { 33 Some(Pid::new(0)) 34 } else { 35 Some(ProcessManager::current_pcb().pid()) 36 }; 37 MMDebugLogManager::log(log_type, source, pid); 38 } 39 40 #[derive(Debug)] 41 pub(super) struct MMDebugLogManager; 42 43 impl MMDebugLogManager { 44 /// 最大的内存分配器日志数量 45 pub const MAX_ALLOC_LOG_NUM: usize = 100000; 46 47 /// 记录内存分配器的日志 48 /// 49 /// ## 参数 50 /// 51 /// - `log_type`:日志类型 52 /// - `source`:日志来源 53 /// - `pid`:日志来源的pid 54 pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) { 55 let id = __MM_DEBUG_LOG_IDA.alloc().unwrap(); 56 let log = AllocatorLog::new( 57 id as u64, 58 log_type, 59 source, 60 pid.map(|p| p.data()), 61 CurrentTimeArch::get_cycles() as u64, 62 ); 63 64 let mut log = log; 65 loop { 66 let r = __MM_ALLOCATOR_LOG_CHANNEL.buf.push(log); 67 if let Err(r) = r { 68 // 如果日志通道满了,就把最早的日志丢弃 69 if __MM_ALLOCATOR_LOG_CHANNEL.buf.remaining() == 0 { 70 __MM_ALLOCATOR_LOG_CHANNEL.buf.pop(); 71 } 72 log = r.into_inner(); 73 } else { 74 break; 75 } 76 } 77 } 78 } 79