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