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, libs::spinlock::SpinLock, 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: SpinLock<ida::IdAllocator> =
20 SpinLock::new(ida::IdAllocator::new(1, usize::MAX).unwrap());
21
22 /// 记录内存分配器的日志
23 ///
24 /// ## 参数
25 ///
26 /// - `log_type`:日志类型
27 /// - `source`:日志来源
mm_debug_log(_log_type: AllocatorLogType, _source: LogSource)28 pub fn mm_debug_log(_log_type: AllocatorLogType, _source: LogSource) {
29 // todo: 由于目前底层的thingbuf存在卡死的问题,因此这里暂时注释掉。
30 // let pid = if unlikely(!ProcessManager::initialized()) {
31 // Some(Pid::new(0))
32 // } else {
33 // Some(ProcessManager::current_pcb().pid())
34 // };
35 // MMDebugLogManager::log(log_type, source, pid);
36 }
37
38 #[derive(Debug)]
39 pub(super) struct MMDebugLogManager;
40
41 impl MMDebugLogManager {
42 /// 最大的内存分配器日志数量
43 pub const MAX_ALLOC_LOG_NUM: usize = 10000;
44
45 /// 记录内存分配器的日志
46 ///
47 /// ## 参数
48 ///
49 /// - `log_type`:日志类型
50 /// - `source`:日志来源
51 /// - `pid`:日志来源的pid
52 #[allow(dead_code)]
log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>)53 pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) {
54 let id = __MM_DEBUG_LOG_IDA.lock_irqsave().alloc().unwrap();
55 let log = AllocatorLog::new(
56 id as u64,
57 log_type,
58 source,
59 pid.map(|p| p.data()),
60 CurrentTimeArch::get_cycles() as u64,
61 );
62
63 let mut log = log;
64 loop {
65 compiler_fence(Ordering::SeqCst);
66 let r = __MM_ALLOCATOR_LOG_CHANNEL.buf.push(log);
67 compiler_fence(Ordering::SeqCst);
68 if let Err(r) = r {
69 // 如果日志通道满了,就把最早的日志丢弃
70 if __MM_ALLOCATOR_LOG_CHANNEL.buf.remaining() == 0 {
71 compiler_fence(Ordering::SeqCst);
72 __MM_ALLOCATOR_LOG_CHANNEL.buf.pop();
73 compiler_fence(Ordering::SeqCst);
74 }
75 log = r.into_inner();
76 compiler_fence(Ordering::SeqCst);
77 } else {
78 break;
79 }
80 }
81 }
82 }
83