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