1 use std::{ 2 path::PathBuf, 3 sync::{mpsc, Arc, Mutex, RwLock, Weak}, 4 thread::JoinHandle, 5 }; 6 7 use log::info; 8 9 use crate::{command::CommandLineArgs, event::Event}; 10 11 pub mod error; 12 pub mod event; 13 mod loader; 14 mod monitor; 15 16 #[derive(Debug)] 17 pub struct AppBackend { 18 _command_line_args: CommandLineArgs, 19 _sender_to_frontend: mpsc::Sender<Event>, 20 data: Arc<Mutex<BackendData>>, 21 main_thread: RwLock<Option<std::thread::JoinHandle<()>>>, 22 /// All threads spawned by the backend.(Except the main thread) 23 threads: Mutex<Vec<JoinHandle<()>>>, 24 } 25 26 impl AppBackend { 27 pub fn new(command_line_args: CommandLineArgs, sender: mpsc::Sender<Event>) -> Arc<Self> { 28 let r = Arc::new(Self { 29 _command_line_args: command_line_args.clone(), 30 _sender_to_frontend: sender.clone(), 31 data: Arc::new(Mutex::new(BackendData::new())), 32 main_thread: RwLock::new(None), 33 threads: Mutex::new(Vec::new()), 34 }); 35 36 r.data.lock().unwrap().kmem_path = Some(PathBuf::from(&command_line_args.kmem)); 37 38 let main_thread = { 39 let cmdargs = command_line_args.clone(); 40 let instance = r.clone(); 41 let sd = sender.clone(); 42 let dt = r.data.clone(); 43 std::thread::spawn(move || { 44 let mut backend = BackendThread::new(cmdargs, sd, Arc::downgrade(&instance), dt); 45 backend.run_main(); 46 }) 47 }; 48 49 *r.main_thread.write().unwrap() = Some(main_thread); 50 51 return r; 52 } 53 } 54 55 #[derive(Debug)] 56 pub(crate) struct BackendData { 57 kernel_metadata: Option<loader::KernelMetadata>, 58 /// Path to the QEMU shm which contains the kernel memory. 59 kmem_path: Option<PathBuf>, 60 } 61 62 impl BackendData { 63 pub fn new() -> Self { 64 Self { 65 kernel_metadata: None, 66 kmem_path: None, 67 } 68 } 69 } 70 71 #[derive(Debug)] 72 pub struct BackendThread { 73 _sender_to_frontend: mpsc::Sender<Event>, 74 command_line_args: CommandLineArgs, 75 shared_data: Arc<Mutex<BackendData>>, 76 backend_instance: Weak<AppBackend>, 77 } 78 79 impl BackendThread { 80 fn new( 81 command_line_args: CommandLineArgs, 82 sender: mpsc::Sender<Event>, 83 backend_instance: Weak<AppBackend>, 84 backend_data: Arc<Mutex<BackendData>>, 85 ) -> Self { 86 Self { 87 command_line_args, 88 _sender_to_frontend: sender, 89 backend_instance, 90 shared_data: backend_data, 91 } 92 } 93 94 pub fn run_main(&mut self) { 95 info!("DragonOS Log Monitor started."); 96 self.load_kernel(); 97 self.run_mm_monitor(); 98 loop { 99 // info!("BackendThread::run()"); 100 std::thread::sleep(std::time::Duration::from_secs(1)); 101 } 102 } 103 104 /// 启动内存管理监视器 105 fn run_mm_monitor(&mut self) { 106 info!("run_mm_monitor()"); 107 let mm_monitor = monitor::mm::MMLogMonitor::new(self.shared_data.clone()); 108 let handle = std::thread::spawn(move || { 109 mm_monitor.run(); 110 }); 111 112 self.backend_instance 113 .upgrade() 114 .unwrap() 115 .threads 116 .lock() 117 .unwrap() 118 .push(handle); 119 } 120 121 /// 加载DragonOS内核并初始化 122 fn load_kernel(&self) { 123 let res = loader::KernelLoader::load(&self.command_line_args.kernel) 124 .expect("Failed to load kernel"); 125 self.shared_data.lock().unwrap().kernel_metadata = Some(res); 126 } 127 } 128