1 use core::{ 2 hint::spin_loop, 3 sync::atomic::{compiler_fence, AtomicBool, Ordering}, 4 }; 5 6 use alloc::{ 7 boxed::Box, 8 collections::LinkedList, 9 string::{String, ToString}, 10 sync::{Arc, Weak}, 11 }; 12 use atomic_enum::atomic_enum; 13 use log::info; 14 use system_error::SystemError; 15 16 use crate::{ 17 arch::CurrentIrqArch, 18 exception::{irqdesc::IrqAction, InterruptArch}, 19 init::initial_kthread::initial_kernel_thread, 20 libs::{once::Once, spinlock::SpinLock}, 21 process::{ProcessManager, ProcessState}, 22 sched::{schedule, SchedMode}, 23 }; 24 25 use super::{fork::CloneFlags, Pid, ProcessControlBlock, ProcessFlags}; 26 27 /// 内核线程的创建任务列表 28 static KTHREAD_CREATE_LIST: SpinLock<LinkedList<Arc<KernelThreadCreateInfo>>> = 29 SpinLock::new(LinkedList::new()); 30 31 static mut KTHREAD_DAEMON_PCB: Option<Arc<ProcessControlBlock>> = None; 32 33 #[derive(Debug)] 34 pub enum WorkerPrivate { 35 KernelThread(KernelThreadPcbPrivate), 36 } 37 38 #[allow(dead_code)] 39 impl WorkerPrivate { 40 pub fn kernel_thread(&self) -> Option<&KernelThreadPcbPrivate> { 41 match self { 42 Self::KernelThread(x) => Some(x), 43 } 44 } 45 46 pub fn kernel_thread_mut(&mut self) -> Option<&mut KernelThreadPcbPrivate> { 47 match self { 48 Self::KernelThread(x) => Some(x), 49 } 50 } 51 } 52 53 bitflags! { 54 pub struct KernelThreadFlags: u32 { 55 const IS_PER_CPU = 1 << 0; 56 const SHOULD_STOP = 1 << 1; 57 const SHOULD_PARK = 1 << 2; 58 } 59 } 60 61 #[derive(Debug)] 62 pub struct KernelThreadPcbPrivate { 63 flags: KernelThreadFlags, 64 } 65 66 #[allow(dead_code)] 67 impl KernelThreadPcbPrivate { 68 pub fn new() -> Self { 69 Self { 70 flags: KernelThreadFlags::empty(), 71 } 72 } 73 74 pub fn flags(&self) -> &KernelThreadFlags { 75 &self.flags 76 } 77 78 pub fn flags_mut(&mut self) -> &mut KernelThreadFlags { 79 &mut self.flags 80 } 81 } 82 83 impl Default for KernelThreadPcbPrivate { 84 fn default() -> Self { 85 Self::new() 86 } 87 } 88 89 /// 内核线程的闭包,参数必须与闭包的参数一致,返回值必须是i32 90 /// 91 /// 元组的第一个元素是闭包,第二个元素是闭包的参数对象 92 /// 93 /// 对于非原始类型的参数,需要使用Box包装 94 #[allow(dead_code)] 95 #[allow(clippy::type_complexity)] 96 pub enum KernelThreadClosure { 97 UsizeClosure((Box<dyn Fn(usize) -> i32 + Send + Sync>, usize)), 98 StaticUsizeClosure((&'static fn(usize) -> i32, usize)), 99 EmptyClosure((Box<dyn Fn() -> i32 + Send + Sync>, ())), 100 StaticEmptyClosure((&'static fn() -> i32, ())), 101 IrqThread( 102 ( 103 &'static dyn Fn(Arc<IrqAction>) -> Result<(), SystemError>, 104 Arc<IrqAction>, 105 ), 106 ), 107 // 添加其他类型入参的闭包,返回值必须是i32 108 } 109 110 unsafe impl Send for KernelThreadClosure {} 111 unsafe impl Sync for KernelThreadClosure {} 112 113 impl KernelThreadClosure { 114 pub fn run(self) -> i32 { 115 match self { 116 Self::UsizeClosure((func, arg)) => func(arg), 117 Self::EmptyClosure((func, _arg)) => func(), 118 Self::StaticUsizeClosure((func, arg)) => func(arg), 119 Self::StaticEmptyClosure((func, _arg)) => func(), 120 Self::IrqThread((func, arg)) => { 121 func(arg).map(|_| 0).unwrap_or_else(|e| e.to_posix_errno()) 122 } 123 } 124 } 125 } 126 127 pub struct KernelThreadCreateInfo { 128 /// 内核线程的入口函数、传入参数 129 closure: SpinLock<Option<Box<KernelThreadClosure>>>, 130 /// 内核线程的名字 131 name: String, 132 /// 是否已经完成创建 todo:使用comletion机制优化这里 133 created: AtomicKernelThreadCreateStatus, 134 result_pcb: SpinLock<Option<Arc<ProcessControlBlock>>>, 135 /// 不安全的Arc引用计数,当内核线程创建失败时,需要减少这个计数 136 has_unsafe_arc_instance: AtomicBool, 137 self_ref: Weak<Self>, 138 /// 如果该值为true在进入bootstrap stage2之后,就会进入睡眠状态 139 to_mark_sleep: AtomicBool, 140 } 141 142 #[atomic_enum] 143 #[derive(PartialEq)] 144 pub enum KernelThreadCreateStatus { 145 Created, 146 NotCreated, 147 ErrorOccured, 148 } 149 150 #[allow(dead_code)] 151 impl KernelThreadCreateInfo { 152 pub fn new(func: KernelThreadClosure, name: String) -> Arc<Self> { 153 let result = Arc::new(Self { 154 closure: SpinLock::new(Some(Box::new(func))), 155 name, 156 created: AtomicKernelThreadCreateStatus::new(KernelThreadCreateStatus::NotCreated), 157 result_pcb: SpinLock::new(None), 158 has_unsafe_arc_instance: AtomicBool::new(false), 159 self_ref: Weak::new(), 160 to_mark_sleep: AtomicBool::new(true), 161 }); 162 let tmp = result.clone(); 163 unsafe { 164 let tmp = Arc::into_raw(tmp) as *mut Self; 165 (*tmp).self_ref = Arc::downgrade(&result); 166 Arc::from_raw(tmp); 167 } 168 169 return result; 170 } 171 172 /// 创建者调用这函数,等待创建完成后,获取创建结果 173 /// 174 /// ## 返回值 175 /// 176 /// - Some(Arc<ProcessControlBlock>) 创建成功,返回新创建的内核线程的PCB 177 /// - None 创建失败 178 pub fn poll_result(&self) -> Option<Arc<ProcessControlBlock>> { 179 loop { 180 match self.created.load(Ordering::SeqCst) { 181 KernelThreadCreateStatus::Created => { 182 return self.result_pcb.lock().take(); 183 } 184 KernelThreadCreateStatus::NotCreated => { 185 spin_loop(); 186 } 187 KernelThreadCreateStatus::ErrorOccured => { 188 // 创建失败,减少不安全的Arc引用计数 189 let to_delete = self.has_unsafe_arc_instance.swap(false, Ordering::SeqCst); 190 if to_delete { 191 let self_ref = self.self_ref.upgrade().unwrap(); 192 unsafe { Arc::decrement_strong_count(&self_ref) }; 193 } 194 return None; 195 } 196 } 197 } 198 } 199 200 pub fn take_closure(&self) -> Option<Box<KernelThreadClosure>> { 201 return self.closure.lock().take(); 202 } 203 204 pub fn name(&self) -> &String { 205 &self.name 206 } 207 208 pub unsafe fn set_create_ok(&self, pcb: Arc<ProcessControlBlock>) { 209 // todo: 使用completion机制优化这里 210 self.result_pcb.lock().replace(pcb); 211 self.created 212 .store(KernelThreadCreateStatus::Created, Ordering::SeqCst); 213 } 214 215 /// 生成一个不安全的Arc指针(用于创建内核线程时传递参数) 216 pub fn generate_unsafe_arc_ptr(self: Arc<Self>) -> *const Self { 217 assert!( 218 self.has_unsafe_arc_instance 219 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 220 .is_ok(), 221 "Cannot generate unsafe arc ptr when there is already one." 222 ); 223 let ptr = Arc::into_raw(self); 224 return ptr; 225 } 226 227 pub unsafe fn parse_unsafe_arc_ptr(ptr: *const Self) -> Arc<Self> { 228 let arc = Arc::from_raw(ptr); 229 assert!( 230 arc.has_unsafe_arc_instance 231 .compare_exchange(true, false, Ordering::SeqCst, Ordering::SeqCst) 232 .is_ok(), 233 "Cannot parse unsafe arc ptr when there is no one." 234 ); 235 assert!(Arc::strong_count(&arc) > 0); 236 return arc; 237 } 238 239 /// 设置是否在进入bootstrap stage2之后,就进入睡眠状态 240 /// 241 /// ## 参数 242 /// 243 /// - to_mark_sleep: 是否在进入bootstrap stage2之后,就进入睡眠状态 244 /// 245 /// ## 返回值 246 /// 如果已经创建完成,返回EINVAL 247 pub fn set_to_mark_sleep(&self, to_mark_sleep: bool) -> Result<(), SystemError> { 248 let result_guard = self.result_pcb.lock(); 249 if result_guard.is_some() { 250 // 已经创建完成,不需要设置 251 return Err(SystemError::EINVAL); 252 } 253 self.to_mark_sleep.store(to_mark_sleep, Ordering::SeqCst); 254 return Ok(()); 255 } 256 257 pub fn to_mark_sleep(&self) -> bool { 258 self.to_mark_sleep.load(Ordering::SeqCst) 259 } 260 } 261 262 pub struct KernelThreadMechanism; 263 264 impl KernelThreadMechanism { 265 pub fn init_stage1() { 266 assert!(ProcessManager::current_pcb().pid() == Pid::new(0)); 267 info!("Initializing kernel thread mechanism stage1..."); 268 269 // 初始化第一个内核线程 270 271 let create_info = KernelThreadCreateInfo::new( 272 KernelThreadClosure::EmptyClosure((Box::new(initial_kernel_thread), ())), 273 "init".to_string(), 274 ); 275 276 let irq_guard: crate::exception::IrqFlagsGuard = 277 unsafe { CurrentIrqArch::save_and_disable_irq() }; 278 // 由于当前是pid=0的idle进程,而__inner_create要求当前是kthread,所以先临时设置为kthread 279 ProcessManager::current_pcb() 280 .flags 281 .get_mut() 282 .insert(ProcessFlags::KTHREAD); 283 create_info 284 .set_to_mark_sleep(false) 285 .expect("Failed to set to_mark_sleep"); 286 287 KernelThreadMechanism::__inner_create( 288 &create_info, 289 CloneFlags::CLONE_VM | CloneFlags::CLONE_SIGNAL, 290 ) 291 .unwrap_or_else(|e| panic!("Failed to create initial kernel thread, error: {:?}", e)); 292 293 ProcessManager::current_pcb() 294 .flags 295 .get_mut() 296 .remove(ProcessFlags::KTHREAD); 297 298 drop(irq_guard); 299 info!("Initializing kernel thread mechanism stage1 complete"); 300 } 301 302 pub fn init_stage2() { 303 assert!(ProcessManager::current_pcb() 304 .flags() 305 .contains(ProcessFlags::KTHREAD)); 306 static INIT: Once = Once::new(); 307 INIT.call_once(|| { 308 info!("Initializing kernel thread mechanism stage2..."); 309 // 初始化kthreadd 310 let closure = KernelThreadClosure::EmptyClosure((Box::new(Self::kthread_daemon), ())); 311 let info = KernelThreadCreateInfo::new(closure, "kthreadd".to_string()); 312 info.set_to_mark_sleep(false) 313 .expect("kthreadadd should be run first"); 314 let kthreadd_pid: Pid = Self::__inner_create( 315 &info, 316 CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 317 ) 318 .expect("Failed to create kthread daemon"); 319 let pcb = ProcessManager::find(kthreadd_pid).unwrap(); 320 ProcessManager::wakeup(&pcb).expect("Failed to wakeup kthread daemon"); 321 unsafe { 322 KTHREAD_DAEMON_PCB.replace(pcb); 323 } 324 info!("Initialize kernel thread mechanism stage2 complete"); 325 }); 326 } 327 328 /// 创建一个新的内核线程 329 /// 330 /// ## 参数 331 /// 332 /// - func: 内核线程的入口函数、传入参数 333 /// - name: 内核线程的名字 334 /// 335 /// ## 返回值 336 /// 337 /// - Some(Arc<ProcessControlBlock>) 创建成功,返回新创建的内核线程的PCB 338 #[allow(dead_code)] 339 pub fn create(func: KernelThreadClosure, name: String) -> Option<Arc<ProcessControlBlock>> { 340 let info = KernelThreadCreateInfo::new(func, name); 341 while unsafe { KTHREAD_DAEMON_PCB.is_none() } { 342 // 等待kthreadd启动 343 spin_loop() 344 } 345 KTHREAD_CREATE_LIST.lock().push_back(info.clone()); 346 compiler_fence(Ordering::SeqCst); 347 ProcessManager::wakeup(unsafe { KTHREAD_DAEMON_PCB.as_ref().unwrap() }) 348 .expect("Failed to wakeup kthread daemon"); 349 return info.poll_result(); 350 } 351 352 /// 创建并运行一个新的内核线程 353 /// 354 /// ## 参数 355 /// 356 /// - func: 内核线程的入口函数、传入参数 357 /// - name: 内核线程的名字 358 /// 359 /// ## 返回值 360 /// 361 /// - Some(Arc<ProcessControlBlock>) 创建成功,返回新创建的内核线程的PCB 362 #[allow(dead_code)] 363 pub fn create_and_run( 364 func: KernelThreadClosure, 365 name: String, 366 ) -> Option<Arc<ProcessControlBlock>> { 367 let pcb = Self::create(func, name)?; 368 ProcessManager::wakeup(&pcb) 369 .unwrap_or_else(|_| panic!("Failed to wakeup kthread: {:?}", pcb.pid())); 370 return Some(pcb); 371 } 372 373 /// 停止一个内核线程 374 /// 375 /// 如果目标内核线程的数据检查失败,会panic 376 /// 377 /// ## 返回值 378 /// 379 /// - Ok(i32) 目标内核线程的退出码 380 #[allow(dead_code)] 381 pub fn stop(pcb: &Arc<ProcessControlBlock>) -> Result<usize, SystemError> { 382 if !pcb.flags().contains(ProcessFlags::KTHREAD) { 383 panic!("Cannt stop a non-kthread process"); 384 } 385 386 let mut worker_private = pcb.worker_private(); 387 assert!( 388 worker_private.is_some(), 389 "kthread stop: worker_private is none, pid: {:?}", 390 pcb.pid() 391 ); 392 worker_private 393 .as_mut() 394 .unwrap() 395 .kernel_thread_mut() 396 .expect("Error type of worker private") 397 .flags 398 .insert(KernelThreadFlags::SHOULD_STOP); 399 400 drop(worker_private); 401 402 ProcessManager::wakeup(pcb).ok(); 403 404 // 忙等目标内核线程退出 405 // todo: 使用completion机制优化这里 406 loop { 407 if let ProcessState::Exited(code) = pcb.sched_info().inner_lock_read_irqsave().state() { 408 return Ok(code); 409 } 410 spin_loop(); 411 } 412 } 413 414 /// 判断一个内核线程是否应当停止 415 /// 416 /// ## 参数 417 /// 418 /// - pcb: 目标内核线程的PCB 419 /// 420 /// ## 返回值 421 /// 422 /// - bool 是否应当停止. true表示应当停止,false表示不应当停止. 如果目标进程不是内核线程,返回false 423 /// 424 /// ## Panic 425 /// 426 /// 如果目标内核线程的数据检查失败,会panic 427 #[allow(dead_code)] 428 pub fn should_stop(pcb: &Arc<ProcessControlBlock>) -> bool { 429 if !pcb.flags().contains(ProcessFlags::KTHREAD) { 430 return false; 431 } 432 433 let worker_private = pcb.worker_private(); 434 assert!( 435 worker_private.is_some(), 436 "kthread should_stop: worker_private is none, pid: {:?}", 437 pcb.pid() 438 ); 439 return worker_private 440 .as_ref() 441 .unwrap() 442 .kernel_thread() 443 .expect("Error type of worker private") 444 .flags 445 .contains(KernelThreadFlags::SHOULD_STOP); 446 } 447 448 /// A daemon thread which creates other kernel threads 449 #[inline(never)] 450 fn kthread_daemon() -> i32 { 451 let current_pcb = ProcessManager::current_pcb(); 452 { 453 // 初始化worker_private 454 let mut worker_private_guard = current_pcb.worker_private(); 455 let worker_private = WorkerPrivate::KernelThread(KernelThreadPcbPrivate::new()); 456 *worker_private_guard = Some(worker_private); 457 } 458 // 设置为kthread 459 current_pcb.flags().insert(ProcessFlags::KTHREAD); 460 drop(current_pcb); 461 462 loop { 463 let mut list = KTHREAD_CREATE_LIST.lock(); 464 while let Some(info) = list.pop_front() { 465 drop(list); 466 // create a new kernel thread 467 let result: Result<Pid, SystemError> = Self::__inner_create( 468 &info, 469 CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 470 ); 471 if result.is_err() { 472 // 创建失败 473 info.created 474 .store(KernelThreadCreateStatus::ErrorOccured, Ordering::SeqCst); 475 }; 476 list = KTHREAD_CREATE_LIST.lock(); 477 } 478 drop(list); 479 480 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 481 ProcessManager::mark_sleep(true).ok(); 482 drop(irq_guard); 483 schedule(SchedMode::SM_NONE); 484 } 485 } 486 } 487 488 /// 内核线程启动的第二阶段 489 /// 490 /// 该函数只能被`kernel_thread_bootstrap_stage1`调用(jmp到该函数) 491 /// 492 /// ## 参数 493 /// 494 /// - ptr: 传入的参数,是一个指向`Arc<KernelThreadCreateInfo>`的指针 495 pub unsafe extern "C" fn kernel_thread_bootstrap_stage2(ptr: *const KernelThreadCreateInfo) -> ! { 496 let info = KernelThreadCreateInfo::parse_unsafe_arc_ptr(ptr); 497 498 let closure: Box<KernelThreadClosure> = info.take_closure().unwrap(); 499 info.set_create_ok(ProcessManager::current_pcb()); 500 let to_mark_sleep = info.to_mark_sleep(); 501 drop(info); 502 503 if to_mark_sleep { 504 // 进入睡眠状态 505 let irq_guard = CurrentIrqArch::save_and_disable_irq(); 506 ProcessManager::mark_sleep(true).expect("Failed to mark sleep"); 507 drop(irq_guard); 508 schedule(SchedMode::SM_NONE); 509 } 510 511 let mut retval = SystemError::EINTR.to_posix_errno(); 512 513 if !KernelThreadMechanism::should_stop(&ProcessManager::current_pcb()) { 514 retval = closure.run(); 515 } 516 517 ProcessManager::exit(retval as usize); 518 } 519 520 /// 初始化内核线程机制 521 #[inline(never)] 522 pub fn kthread_init() { 523 static INIT: Once = Once::new(); 524 INIT.call_once(|| { 525 KernelThreadMechanism::init_stage1(); 526 }); 527 } 528