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`:日志来源
mm_debug_log(_log_type: AllocatorLogType, _source: LogSource)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)]
log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>)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