xref: /DragonOS/kernel/src/debug/klog/mm.rs (revision c75ef4e2126c180bf04c08635ffa5a278619c035)
17b32f508SLoGin extern crate klog_types;
27b32f508SLoGin 
37b32f508SLoGin use core::intrinsics::unlikely;
47b32f508SLoGin 
57b32f508SLoGin use klog_types::{AllocatorLog, AllocatorLogType, LogSource, MMLogChannel};
67b32f508SLoGin 
77b32f508SLoGin use crate::{
87b32f508SLoGin     arch::CurrentTimeArch,
97b32f508SLoGin     process::{Pid, ProcessManager},
107b32f508SLoGin     time::TimeArch,
117b32f508SLoGin };
127b32f508SLoGin 
137b32f508SLoGin /// 全局的内存分配器日志通道
147b32f508SLoGin ///
157b32f508SLoGin /// 标记为`no_mangle`是为了让调试器能够找到这个变量
167b32f508SLoGin #[no_mangle]
177b32f508SLoGin static __MM_ALLOCATOR_LOG_CHANNEL: MMLogChannel<{ MMDebugLogManager::MAX_ALLOC_LOG_NUM }> =
187b32f508SLoGin     MMLogChannel::new(MMDebugLogManager::MAX_ALLOC_LOG_NUM);
197b32f508SLoGin 
207b32f508SLoGin /// 全局的内存分配器日志id分配器
217b32f508SLoGin ///
227b32f508SLoGin /// id从1开始, 因为0是无效的id
237b32f508SLoGin static __MM_DEBUG_LOG_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX);
247b32f508SLoGin 
257b32f508SLoGin /// 记录内存分配器的日志
267b32f508SLoGin ///
277b32f508SLoGin /// ## 参数
287b32f508SLoGin ///
297b32f508SLoGin /// - `log_type`:日志类型
307b32f508SLoGin /// - `source`:日志来源
317b32f508SLoGin pub fn mm_debug_log(log_type: AllocatorLogType, source: LogSource) {
327b32f508SLoGin     let pid = if unlikely(!ProcessManager::initialized()) {
337b32f508SLoGin         Some(Pid::new(0))
347b32f508SLoGin     } else {
357b32f508SLoGin         Some(ProcessManager::current_pcb().pid())
367b32f508SLoGin     };
377b32f508SLoGin     MMDebugLogManager::log(log_type, source, pid);
387b32f508SLoGin }
397b32f508SLoGin 
407b32f508SLoGin #[derive(Debug)]
417b32f508SLoGin pub(super) struct MMDebugLogManager;
427b32f508SLoGin 
437b32f508SLoGin impl MMDebugLogManager {
447b32f508SLoGin     /// 最大的内存分配器日志数量
45*c75ef4e2SLoGin     pub const MAX_ALLOC_LOG_NUM: usize = 10000;
467b32f508SLoGin 
477b32f508SLoGin     /// 记录内存分配器的日志
487b32f508SLoGin     ///
497b32f508SLoGin     /// ## 参数
507b32f508SLoGin     ///
517b32f508SLoGin     /// - `log_type`:日志类型
527b32f508SLoGin     /// - `source`:日志来源
537b32f508SLoGin     /// - `pid`:日志来源的pid
547b32f508SLoGin     pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) {
557b32f508SLoGin         let id = __MM_DEBUG_LOG_IDA.alloc().unwrap();
567b32f508SLoGin         let log = AllocatorLog::new(
577b32f508SLoGin             id as u64,
587b32f508SLoGin             log_type,
597b32f508SLoGin             source,
607b32f508SLoGin             pid.map(|p| p.data()),
617b32f508SLoGin             CurrentTimeArch::get_cycles() as u64,
627b32f508SLoGin         );
637b32f508SLoGin 
647b32f508SLoGin         let mut log = log;
657b32f508SLoGin         loop {
667b32f508SLoGin             let r = __MM_ALLOCATOR_LOG_CHANNEL.buf.push(log);
677b32f508SLoGin             if let Err(r) = r {
687b32f508SLoGin                 // 如果日志通道满了,就把最早的日志丢弃
697b32f508SLoGin                 if __MM_ALLOCATOR_LOG_CHANNEL.buf.remaining() == 0 {
707b32f508SLoGin                     __MM_ALLOCATOR_LOG_CHANNEL.buf.pop();
717b32f508SLoGin                 }
727b32f508SLoGin                 log = r.into_inner();
737b32f508SLoGin             } else {
747b32f508SLoGin                 break;
757b32f508SLoGin             }
767b32f508SLoGin         }
777b32f508SLoGin     }
787b32f508SLoGin }
79