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