xref: /DragonOS/kernel/src/debug/klog/mm.rs (revision da152319797436368304cbc3f85a3b9ec049134b) !
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 = 10000;
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