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