xref: /DragonOS/kernel/src/debug/klog/mm.rs (revision 352ee04918f4585ad4f8a896ca6e18b1ef7d7934)
17b32f508SLoGin extern crate klog_types;
27b32f508SLoGin 
3*352ee049SLoGin use core::sync::atomic::{compiler_fence, Ordering};
47b32f508SLoGin 
57b32f508SLoGin use klog_types::{AllocatorLog, AllocatorLogType, LogSource, MMLogChannel};
67b32f508SLoGin 
7*352ee049SLoGin use crate::{arch::CurrentTimeArch, process::Pid, time::TimeArch};
87b32f508SLoGin 
97b32f508SLoGin /// 全局的内存分配器日志通道
107b32f508SLoGin ///
117b32f508SLoGin /// 标记为`no_mangle`是为了让调试器能够找到这个变量
127b32f508SLoGin #[no_mangle]
137b32f508SLoGin static __MM_ALLOCATOR_LOG_CHANNEL: MMLogChannel<{ MMDebugLogManager::MAX_ALLOC_LOG_NUM }> =
147b32f508SLoGin     MMLogChannel::new(MMDebugLogManager::MAX_ALLOC_LOG_NUM);
157b32f508SLoGin 
167b32f508SLoGin /// 全局的内存分配器日志id分配器
177b32f508SLoGin ///
187b32f508SLoGin /// id从1开始, 因为0是无效的id
197b32f508SLoGin static __MM_DEBUG_LOG_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX);
207b32f508SLoGin 
217b32f508SLoGin /// 记录内存分配器的日志
227b32f508SLoGin ///
237b32f508SLoGin /// ## 参数
247b32f508SLoGin ///
257b32f508SLoGin /// - `log_type`:日志类型
267b32f508SLoGin /// - `source`:日志来源
27*352ee049SLoGin pub fn mm_debug_log(_log_type: AllocatorLogType, _source: LogSource) {
28*352ee049SLoGin     // todo: 由于目前底层的thingbuf存在卡死的问题,因此这里暂时注释掉。
29*352ee049SLoGin     // let pid = if unlikely(!ProcessManager::initialized()) {
30*352ee049SLoGin     //     Some(Pid::new(0))
31*352ee049SLoGin     // } else {
32*352ee049SLoGin     //     Some(ProcessManager::current_pcb().pid())
33*352ee049SLoGin     // };
34*352ee049SLoGin     // MMDebugLogManager::log(log_type, source, pid);
357b32f508SLoGin }
367b32f508SLoGin 
377b32f508SLoGin #[derive(Debug)]
387b32f508SLoGin pub(super) struct MMDebugLogManager;
397b32f508SLoGin 
407b32f508SLoGin impl MMDebugLogManager {
417b32f508SLoGin     /// 最大的内存分配器日志数量
42c75ef4e2SLoGin     pub const MAX_ALLOC_LOG_NUM: usize = 10000;
437b32f508SLoGin 
447b32f508SLoGin     /// 记录内存分配器的日志
457b32f508SLoGin     ///
467b32f508SLoGin     /// ## 参数
477b32f508SLoGin     ///
487b32f508SLoGin     /// - `log_type`:日志类型
497b32f508SLoGin     /// - `source`:日志来源
507b32f508SLoGin     /// - `pid`:日志来源的pid
51*352ee049SLoGin     #[allow(dead_code)]
527b32f508SLoGin     pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) {
537b32f508SLoGin         let id = __MM_DEBUG_LOG_IDA.alloc().unwrap();
547b32f508SLoGin         let log = AllocatorLog::new(
557b32f508SLoGin             id as u64,
567b32f508SLoGin             log_type,
577b32f508SLoGin             source,
587b32f508SLoGin             pid.map(|p| p.data()),
597b32f508SLoGin             CurrentTimeArch::get_cycles() as u64,
607b32f508SLoGin         );
617b32f508SLoGin 
627b32f508SLoGin         let mut log = log;
637b32f508SLoGin         loop {
64b8ed3825SDonkey Kane             compiler_fence(Ordering::SeqCst);
657b32f508SLoGin             let r = __MM_ALLOCATOR_LOG_CHANNEL.buf.push(log);
66b8ed3825SDonkey Kane             compiler_fence(Ordering::SeqCst);
677b32f508SLoGin             if let Err(r) = r {
687b32f508SLoGin                 // 如果日志通道满了,就把最早的日志丢弃
697b32f508SLoGin                 if __MM_ALLOCATOR_LOG_CHANNEL.buf.remaining() == 0 {
70b8ed3825SDonkey Kane                     compiler_fence(Ordering::SeqCst);
717b32f508SLoGin                     __MM_ALLOCATOR_LOG_CHANNEL.buf.pop();
72b8ed3825SDonkey Kane                     compiler_fence(Ordering::SeqCst);
737b32f508SLoGin                 }
747b32f508SLoGin                 log = r.into_inner();
75b8ed3825SDonkey Kane                 compiler_fence(Ordering::SeqCst);
767b32f508SLoGin             } else {
777b32f508SLoGin                 break;
787b32f508SLoGin             }
797b32f508SLoGin         }
807b32f508SLoGin     }
817b32f508SLoGin }
82