1 use core::{ 2 hash::{Hash, Hasher}, 3 hint::spin_loop, 4 intrinsics::{likely, unlikely}, 5 mem::ManuallyDrop, 6 sync::atomic::{compiler_fence, AtomicBool, AtomicI32, AtomicIsize, AtomicUsize, Ordering}, 7 }; 8 9 use alloc::{ 10 string::{String, ToString}, 11 sync::{Arc, Weak}, 12 vec::Vec, 13 }; 14 use hashbrown::HashMap; 15 use system_error::SystemError; 16 17 use crate::{ 18 arch::{ 19 ipc::signal::{AtomicSignal, SigSet, Signal}, 20 process::ArchPCBInfo, 21 sched::sched, 22 CurrentIrqArch, 23 }, 24 driver::tty::tty_core::TtyCore, 25 exception::InterruptArch, 26 filesystem::{ 27 procfs::procfs_unregister_pid, 28 vfs::{file::FileDescriptorVec, FileType}, 29 }, 30 ipc::signal_types::{SigInfo, SigPending, SignalStruct}, 31 kdebug, kinfo, 32 libs::{ 33 align::AlignedBox, 34 casting::DowncastArc, 35 futex::{ 36 constant::{FutexFlag, FUTEX_BITSET_MATCH_ANY}, 37 futex::Futex, 38 }, 39 lock_free_flags::LockFreeFlags, 40 rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard}, 41 spinlock::{SpinLock, SpinLockGuard}, 42 wait_queue::WaitQueue, 43 }, 44 mm::{percpu::PerCpuVar, set_INITIAL_PROCESS_ADDRESS_SPACE, ucontext::AddressSpace, VirtAddr}, 45 net::socket::SocketInode, 46 sched::{ 47 completion::Completion, 48 core::{sched_enqueue, CPU_EXECUTING}, 49 SchedPolicy, SchedPriority, 50 }, 51 smp::kick_cpu, 52 syscall::{user_access::clear_user, Syscall}, 53 }; 54 55 use self::kthread::WorkerPrivate; 56 57 pub mod abi; 58 pub mod c_adapter; 59 pub mod exec; 60 pub mod exit; 61 pub mod fork; 62 pub mod idle; 63 pub mod kthread; 64 pub mod pid; 65 pub mod process; 66 pub mod resource; 67 pub mod syscall; 68 69 /// 系统中所有进程的pcb 70 static ALL_PROCESS: SpinLock<Option<HashMap<Pid, Arc<ProcessControlBlock>>>> = SpinLock::new(None); 71 72 pub static mut SWITCH_RESULT: Option<PerCpuVar<SwitchResult>> = None; 73 74 /// 一个只改变1次的全局变量,标志进程管理器是否已经初始化完成 75 static mut __PROCESS_MANAGEMENT_INIT_DONE: bool = false; 76 77 #[derive(Debug)] 78 pub struct SwitchResult { 79 pub prev_pcb: Option<Arc<ProcessControlBlock>>, 80 pub next_pcb: Option<Arc<ProcessControlBlock>>, 81 } 82 83 impl SwitchResult { 84 pub fn new() -> Self { 85 Self { 86 prev_pcb: None, 87 next_pcb: None, 88 } 89 } 90 } 91 92 #[derive(Debug)] 93 pub struct ProcessManager; 94 impl ProcessManager { 95 #[inline(never)] 96 fn init() { 97 static INIT_FLAG: AtomicBool = AtomicBool::new(false); 98 if INIT_FLAG 99 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 100 .is_err() 101 { 102 panic!("ProcessManager has been initialized!"); 103 } 104 105 unsafe { 106 compiler_fence(Ordering::SeqCst); 107 kdebug!("To create address space for INIT process."); 108 // test_buddy(); 109 set_INITIAL_PROCESS_ADDRESS_SPACE( 110 AddressSpace::new(true).expect("Failed to create address space for INIT process."), 111 ); 112 kdebug!("INIT process address space created."); 113 compiler_fence(Ordering::SeqCst); 114 }; 115 116 ALL_PROCESS.lock_irqsave().replace(HashMap::new()); 117 Self::arch_init(); 118 kdebug!("process arch init done."); 119 Self::init_idle(); 120 kdebug!("process idle init done."); 121 122 unsafe { __PROCESS_MANAGEMENT_INIT_DONE = true }; 123 kinfo!("Process Manager initialized."); 124 } 125 126 /// 判断进程管理器是否已经初始化完成 127 pub fn initialized() -> bool { 128 unsafe { __PROCESS_MANAGEMENT_INIT_DONE } 129 } 130 131 /// 获取当前进程的pcb 132 pub fn current_pcb() -> Arc<ProcessControlBlock> { 133 if unlikely(unsafe { !__PROCESS_MANAGEMENT_INIT_DONE }) { 134 kerror!("unsafe__PROCESS_MANAGEMENT_INIT_DONE == false"); 135 loop { 136 spin_loop(); 137 } 138 } 139 return ProcessControlBlock::arch_current_pcb(); 140 } 141 142 /// 获取当前进程的pid 143 /// 144 /// 如果进程管理器未初始化完成,那么返回0 145 pub fn current_pid() -> Pid { 146 if unlikely(unsafe { !__PROCESS_MANAGEMENT_INIT_DONE }) { 147 return Pid(0); 148 } 149 150 return ProcessManager::current_pcb().pid(); 151 } 152 153 /// 增加当前进程的锁持有计数 154 #[inline(always)] 155 pub fn preempt_disable() { 156 if likely(unsafe { __PROCESS_MANAGEMENT_INIT_DONE }) { 157 ProcessManager::current_pcb().preempt_disable(); 158 } 159 } 160 161 /// 减少当前进程的锁持有计数 162 #[inline(always)] 163 pub fn preempt_enable() { 164 if likely(unsafe { __PROCESS_MANAGEMENT_INIT_DONE }) { 165 ProcessManager::current_pcb().preempt_enable(); 166 } 167 } 168 169 /// 根据pid获取进程的pcb 170 /// 171 /// ## 参数 172 /// 173 /// - `pid` : 进程的pid 174 /// 175 /// ## 返回值 176 /// 177 /// 如果找到了对应的进程,那么返回该进程的pcb,否则返回None 178 pub fn find(pid: Pid) -> Option<Arc<ProcessControlBlock>> { 179 return ALL_PROCESS.lock_irqsave().as_ref()?.get(&pid).cloned(); 180 } 181 182 /// 向系统中添加一个进程的pcb 183 /// 184 /// ## 参数 185 /// 186 /// - `pcb` : 进程的pcb 187 /// 188 /// ## 返回值 189 /// 190 /// 无 191 pub fn add_pcb(pcb: Arc<ProcessControlBlock>) { 192 ALL_PROCESS 193 .lock_irqsave() 194 .as_mut() 195 .unwrap() 196 .insert(pcb.pid(), pcb.clone()); 197 } 198 199 /// 唤醒一个进程 200 pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> { 201 let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 202 let state = pcb.sched_info().inner_lock_read_irqsave().state(); 203 if state.is_blocked() { 204 let mut writer = pcb.sched_info().inner_lock_write_irqsave(); 205 let state = writer.state(); 206 if state.is_blocked() { 207 writer.set_state(ProcessState::Runnable); 208 // avoid deadlock 209 drop(writer); 210 211 sched_enqueue(pcb.clone(), true); 212 return Ok(()); 213 } else if state.is_exited() { 214 return Err(SystemError::EINVAL); 215 } else { 216 return Ok(()); 217 } 218 } else if state.is_exited() { 219 return Err(SystemError::EINVAL); 220 } else { 221 return Ok(()); 222 } 223 } 224 225 /// 唤醒暂停的进程 226 pub fn wakeup_stop(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> { 227 let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 228 let state = pcb.sched_info().inner_lock_read_irqsave().state(); 229 if let ProcessState::Stopped = state { 230 let mut writer = pcb.sched_info().inner_lock_write_irqsave(); 231 let state = writer.state(); 232 if let ProcessState::Stopped = state { 233 writer.set_state(ProcessState::Runnable); 234 // avoid deadlock 235 drop(writer); 236 237 sched_enqueue(pcb.clone(), true); 238 return Ok(()); 239 } else if state.is_runnable() { 240 return Ok(()); 241 } else { 242 return Err(SystemError::EINVAL); 243 } 244 } else if state.is_runnable() { 245 return Ok(()); 246 } else { 247 return Err(SystemError::EINVAL); 248 } 249 } 250 251 /// 标志当前进程永久睡眠,但是发起调度的工作,应该由调用者完成 252 /// 253 /// ## 注意 254 /// 255 /// - 进入当前函数之前,不能持有sched_info的锁 256 /// - 进入当前函数之前,必须关闭中断 257 /// - 进入当前函数之后必须保证逻辑的正确性,避免被重复加入调度队列 258 pub fn mark_sleep(interruptable: bool) -> Result<(), SystemError> { 259 assert_eq!( 260 CurrentIrqArch::is_irq_enabled(), 261 false, 262 "interrupt must be disabled before enter ProcessManager::mark_sleep()" 263 ); 264 265 let pcb = ProcessManager::current_pcb(); 266 let mut writer = pcb.sched_info().inner_lock_write_irqsave(); 267 if !matches!(writer.state(), ProcessState::Exited(_)) { 268 writer.set_state(ProcessState::Blocked(interruptable)); 269 pcb.flags().insert(ProcessFlags::NEED_SCHEDULE); 270 drop(writer); 271 272 return Ok(()); 273 } 274 return Err(SystemError::EINTR); 275 } 276 277 /// 标志当前进程为停止状态,但是发起调度的工作,应该由调用者完成 278 /// 279 /// ## 注意 280 /// 281 /// - 进入当前函数之前,不能持有sched_info的锁 282 /// - 进入当前函数之前,必须关闭中断 283 pub fn mark_stop() -> Result<(), SystemError> { 284 assert_eq!( 285 CurrentIrqArch::is_irq_enabled(), 286 false, 287 "interrupt must be disabled before enter ProcessManager::mark_stop()" 288 ); 289 290 let pcb = ProcessManager::current_pcb(); 291 let mut writer = pcb.sched_info().inner_lock_write_irqsave(); 292 if !matches!(writer.state(), ProcessState::Exited(_)) { 293 writer.set_state(ProcessState::Stopped); 294 pcb.flags().insert(ProcessFlags::NEED_SCHEDULE); 295 drop(writer); 296 297 return Ok(()); 298 } 299 return Err(SystemError::EINTR); 300 } 301 /// 当子进程退出后向父进程发送通知 302 fn exit_notify() { 303 let current = ProcessManager::current_pcb(); 304 // 让INIT进程收养所有子进程 305 if current.pid() != Pid(1) { 306 unsafe { 307 current 308 .adopt_childen() 309 .unwrap_or_else(|e| panic!("adopte_childen failed: error: {e:?}")) 310 }; 311 let r = current.parent_pcb.read().upgrade(); 312 if r.is_none() { 313 return; 314 } 315 let parent_pcb = r.unwrap(); 316 let r = Syscall::kill(parent_pcb.pid(), Signal::SIGCHLD as i32); 317 if r.is_err() { 318 kwarn!( 319 "failed to send kill signal to {:?}'s parent pcb {:?}", 320 current.pid(), 321 parent_pcb.pid() 322 ); 323 } 324 // todo: 这里需要向父进程发送SIGCHLD信号 325 // todo: 这里还需要根据线程组的信息,决定信号的发送 326 } 327 } 328 329 /// 退出当前进程 330 /// 331 /// ## 参数 332 /// 333 /// - `exit_code` : 进程的退出码 334 pub fn exit(exit_code: usize) -> ! { 335 // 关中断 336 unsafe { CurrentIrqArch::interrupt_disable() }; 337 let pcb = ProcessManager::current_pcb(); 338 pcb.sched_info 339 .inner_lock_write_irqsave() 340 .set_state(ProcessState::Exited(exit_code)); 341 pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true))); 342 343 // 进行进程退出后的工作 344 let thread = pcb.thread.write(); 345 if let Some(addr) = thread.set_child_tid { 346 unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") }; 347 } 348 349 if let Some(addr) = thread.clear_child_tid { 350 if Arc::strong_count(&pcb.basic().user_vm().expect("User VM Not found")) > 1 { 351 let _ = 352 Futex::futex_wake(addr, FutexFlag::FLAGS_MATCH_NONE, 1, FUTEX_BITSET_MATCH_ANY); 353 } 354 unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") }; 355 } 356 357 // 如果是vfork出来的进程,则需要处理completion 358 if thread.vfork_done.is_some() { 359 thread.vfork_done.as_ref().unwrap().complete_all(); 360 } 361 drop(thread); 362 unsafe { pcb.basic_mut().set_user_vm(None) }; 363 drop(pcb); 364 ProcessManager::exit_notify(); 365 unsafe { CurrentIrqArch::interrupt_enable() }; 366 367 sched(); 368 loop {} 369 } 370 371 pub unsafe fn release(pid: Pid) { 372 let pcb = ProcessManager::find(pid); 373 if pcb.is_some() { 374 // let pcb = pcb.unwrap(); 375 // 判断该pcb是否在全局没有任何引用 376 // TODO: 当前,pcb的Arc指针存在泄露问题,引用计数不正确,打算在接下来实现debug专用的Arc,方便调试,然后解决这个bug。 377 // 因此目前暂时注释掉,使得能跑 378 // if Arc::strong_count(&pcb) <= 2 { 379 // drop(pcb); 380 // ALL_PROCESS.lock().as_mut().unwrap().remove(&pid); 381 // } else { 382 // // 如果不为1就panic 383 // let msg = format!("pcb '{:?}' is still referenced, strong count={}",pcb.pid(), Arc::strong_count(&pcb)); 384 // kerror!("{}", msg); 385 // panic!() 386 // } 387 388 ALL_PROCESS.lock_irqsave().as_mut().unwrap().remove(&pid); 389 } 390 } 391 392 /// 上下文切换完成后的钩子函数 393 unsafe fn switch_finish_hook() { 394 // kdebug!("switch_finish_hook"); 395 let prev_pcb = SWITCH_RESULT 396 .as_mut() 397 .unwrap() 398 .get_mut() 399 .prev_pcb 400 .take() 401 .expect("prev_pcb is None"); 402 let next_pcb = SWITCH_RESULT 403 .as_mut() 404 .unwrap() 405 .get_mut() 406 .next_pcb 407 .take() 408 .expect("next_pcb is None"); 409 410 // 由于进程切换前使用了SpinLockGuard::leak(),所以这里需要手动释放锁 411 prev_pcb.arch_info.force_unlock(); 412 next_pcb.arch_info.force_unlock(); 413 } 414 415 /// 如果目标进程正在目标CPU上运行,那么就让这个cpu陷入内核态 416 /// 417 /// ## 参数 418 /// 419 /// - `pcb` : 进程的pcb 420 #[allow(dead_code)] 421 pub fn kick(pcb: &Arc<ProcessControlBlock>) { 422 ProcessManager::current_pcb().preempt_disable(); 423 let cpu_id = pcb.sched_info().on_cpu(); 424 425 if let Some(cpu_id) = cpu_id { 426 let cpu_id = cpu_id; 427 428 if pcb.pid() == CPU_EXECUTING.get(cpu_id) { 429 kick_cpu(cpu_id).expect("ProcessManager::kick(): Failed to kick cpu"); 430 } 431 } 432 433 ProcessManager::current_pcb().preempt_enable(); 434 } 435 } 436 437 /// 上下文切换的钩子函数,当这个函数return的时候,将会发生上下文切换 438 #[cfg(target_arch = "x86_64")] 439 pub unsafe extern "sysv64" fn switch_finish_hook() { 440 ProcessManager::switch_finish_hook(); 441 } 442 #[cfg(target_arch = "riscv64")] 443 pub unsafe extern "C" fn switch_finish_hook() { 444 ProcessManager::switch_finish_hook(); 445 } 446 447 int_like!(Pid, AtomicPid, usize, AtomicUsize); 448 449 impl Hash for Pid { 450 fn hash<H: Hasher>(&self, state: &mut H) { 451 self.0.hash(state); 452 } 453 } 454 455 impl Pid { 456 pub fn to_string(&self) -> String { 457 self.0.to_string() 458 } 459 } 460 461 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 462 pub enum ProcessState { 463 /// The process is running on a CPU or in a run queue. 464 Runnable, 465 /// The process is waiting for an event to occur. 466 /// 其中的bool表示该等待过程是否可以被打断。 467 /// - 如果该bool为true,那么,硬件中断/信号/其他系统事件都可以打断该等待过程,使得该进程重新进入Runnable状态。 468 /// - 如果该bool为false,那么,这个进程必须被显式的唤醒,才能重新进入Runnable状态。 469 Blocked(bool), 470 /// 进程被信号终止 471 Stopped, 472 /// 进程已经退出,usize表示进程的退出码 473 Exited(usize), 474 } 475 476 #[allow(dead_code)] 477 impl ProcessState { 478 #[inline(always)] 479 pub fn is_runnable(&self) -> bool { 480 return matches!(self, ProcessState::Runnable); 481 } 482 483 #[inline(always)] 484 pub fn is_blocked(&self) -> bool { 485 return matches!(self, ProcessState::Blocked(_)); 486 } 487 488 #[inline(always)] 489 pub fn is_blocked_interruptable(&self) -> bool { 490 return matches!(self, ProcessState::Blocked(true)); 491 } 492 493 /// Returns `true` if the process state is [`Exited`]. 494 #[inline(always)] 495 pub fn is_exited(&self) -> bool { 496 return matches!(self, ProcessState::Exited(_)); 497 } 498 499 /// Returns `true` if the process state is [`Stopped`]. 500 /// 501 /// [`Stopped`]: ProcessState::Stopped 502 #[inline(always)] 503 pub fn is_stopped(&self) -> bool { 504 matches!(self, ProcessState::Stopped) 505 } 506 507 /// Returns exit code if the process state is [`Exited`]. 508 #[inline(always)] 509 pub fn exit_code(&self) -> Option<usize> { 510 match self { 511 ProcessState::Exited(code) => Some(*code), 512 _ => None, 513 } 514 } 515 } 516 517 bitflags! { 518 /// pcb的标志位 519 pub struct ProcessFlags: usize { 520 /// 当前pcb表示一个内核线程 521 const KTHREAD = 1 << 0; 522 /// 当前进程需要被调度 523 const NEED_SCHEDULE = 1 << 1; 524 /// 进程由于vfork而与父进程存在资源共享 525 const VFORK = 1 << 2; 526 /// 进程不可被冻结 527 const NOFREEZE = 1 << 3; 528 /// 进程正在退出 529 const EXITING = 1 << 4; 530 /// 进程由于接收到终止信号唤醒 531 const WAKEKILL = 1 << 5; 532 /// 进程由于接收到信号而退出.(Killed by a signal) 533 const SIGNALED = 1 << 6; 534 /// 进程需要迁移到其他cpu上 535 const NEED_MIGRATE = 1 << 7; 536 /// 随机化的虚拟地址空间,主要用于动态链接器的加载 537 const RANDOMIZE = 1 << 8; 538 } 539 } 540 541 #[derive(Debug)] 542 pub struct ProcessControlBlock { 543 /// 当前进程的pid 544 pid: Pid, 545 /// 当前进程的线程组id(这个值在同一个线程组内永远不变) 546 tgid: Pid, 547 548 basic: RwLock<ProcessBasicInfo>, 549 /// 当前进程的自旋锁持有计数 550 preempt_count: AtomicUsize, 551 552 flags: LockFreeFlags<ProcessFlags>, 553 worker_private: SpinLock<Option<WorkerPrivate>>, 554 /// 进程的内核栈 555 kernel_stack: RwLock<KernelStack>, 556 557 /// 系统调用栈 558 syscall_stack: RwLock<KernelStack>, 559 560 /// 与调度相关的信息 561 sched_info: ProcessSchedulerInfo, 562 /// 与处理器架构相关的信息 563 arch_info: SpinLock<ArchPCBInfo>, 564 /// 与信号处理相关的信息(似乎可以是无锁的) 565 sig_info: RwLock<ProcessSignalInfo>, 566 /// 信号处理结构体 567 sig_struct: SpinLock<SignalStruct>, 568 /// 退出信号S 569 exit_signal: AtomicSignal, 570 571 /// 父进程指针 572 parent_pcb: RwLock<Weak<ProcessControlBlock>>, 573 /// 真实父进程指针 574 real_parent_pcb: RwLock<Weak<ProcessControlBlock>>, 575 576 /// 子进程链表 577 children: RwLock<Vec<Pid>>, 578 579 /// 等待队列 580 wait_queue: WaitQueue, 581 582 /// 线程信息 583 thread: RwLock<ThreadInfo>, 584 } 585 586 impl ProcessControlBlock { 587 /// Generate a new pcb. 588 /// 589 /// ## 参数 590 /// 591 /// - `name` : 进程的名字 592 /// - `kstack` : 进程的内核栈 593 /// 594 /// ## 返回值 595 /// 596 /// 返回一个新的pcb 597 pub fn new(name: String, kstack: KernelStack) -> Arc<Self> { 598 return Self::do_create_pcb(name, kstack, false); 599 } 600 601 /// 创建一个新的idle进程 602 /// 603 /// 请注意,这个函数只能在进程管理初始化的时候调用。 604 pub fn new_idle(cpu_id: u32, kstack: KernelStack) -> Arc<Self> { 605 let name = format!("idle-{}", cpu_id); 606 return Self::do_create_pcb(name, kstack, true); 607 } 608 609 #[inline(never)] 610 fn do_create_pcb(name: String, kstack: KernelStack, is_idle: bool) -> Arc<Self> { 611 let (pid, ppid, cwd) = if is_idle { 612 (Pid(0), Pid(0), "/".to_string()) 613 } else { 614 let ppid = ProcessManager::current_pcb().pid(); 615 let cwd = ProcessManager::current_pcb().basic().cwd(); 616 (Self::generate_pid(), ppid, cwd) 617 }; 618 619 let basic_info = ProcessBasicInfo::new(Pid(0), ppid, name, cwd, None); 620 let preempt_count = AtomicUsize::new(0); 621 let flags = unsafe { LockFreeFlags::new(ProcessFlags::empty()) }; 622 623 let sched_info = ProcessSchedulerInfo::new(None); 624 let arch_info = SpinLock::new(ArchPCBInfo::new(&kstack)); 625 626 let ppcb: Weak<ProcessControlBlock> = ProcessManager::find(ppid) 627 .map(|p| Arc::downgrade(&p)) 628 .unwrap_or_else(|| Weak::new()); 629 630 let pcb = Self { 631 pid, 632 tgid: pid, 633 basic: basic_info, 634 preempt_count, 635 flags, 636 kernel_stack: RwLock::new(kstack), 637 syscall_stack: RwLock::new(KernelStack::new().unwrap()), 638 worker_private: SpinLock::new(None), 639 sched_info, 640 arch_info, 641 sig_info: RwLock::new(ProcessSignalInfo::default()), 642 sig_struct: SpinLock::new(SignalStruct::new()), 643 exit_signal: AtomicSignal::new(Signal::SIGCHLD), 644 parent_pcb: RwLock::new(ppcb.clone()), 645 real_parent_pcb: RwLock::new(ppcb), 646 children: RwLock::new(Vec::new()), 647 wait_queue: WaitQueue::INIT, 648 thread: RwLock::new(ThreadInfo::new()), 649 }; 650 651 // 初始化系统调用栈 652 #[cfg(target_arch = "x86_64")] 653 pcb.arch_info 654 .lock() 655 .init_syscall_stack(&pcb.syscall_stack.read()); 656 657 let pcb = Arc::new(pcb); 658 659 // 设置进程的arc指针到内核栈和系统调用栈的最低地址处 660 unsafe { 661 pcb.kernel_stack 662 .write() 663 .set_pcb(Arc::downgrade(&pcb)) 664 .unwrap(); 665 666 pcb.syscall_stack 667 .write() 668 .set_pcb(Arc::downgrade(&pcb)) 669 .unwrap() 670 }; 671 672 // 将当前pcb加入父进程的子进程哈希表中 673 if pcb.pid() > Pid(1) { 674 if let Some(ppcb_arc) = pcb.parent_pcb.read().upgrade() { 675 let mut children = ppcb_arc.children.write_irqsave(); 676 children.push(pcb.pid()); 677 } else { 678 panic!("parent pcb is None"); 679 } 680 } 681 682 return pcb; 683 } 684 685 /// 生成一个新的pid 686 #[inline(always)] 687 fn generate_pid() -> Pid { 688 static NEXT_PID: AtomicPid = AtomicPid::new(Pid(1)); 689 return NEXT_PID.fetch_add(Pid(1), Ordering::SeqCst); 690 } 691 692 /// 返回当前进程的锁持有计数 693 #[inline(always)] 694 pub fn preempt_count(&self) -> usize { 695 return self.preempt_count.load(Ordering::SeqCst); 696 } 697 698 /// 增加当前进程的锁持有计数 699 #[inline(always)] 700 pub fn preempt_disable(&self) { 701 self.preempt_count.fetch_add(1, Ordering::SeqCst); 702 } 703 704 /// 减少当前进程的锁持有计数 705 #[inline(always)] 706 pub fn preempt_enable(&self) { 707 self.preempt_count.fetch_sub(1, Ordering::SeqCst); 708 } 709 710 #[inline(always)] 711 pub unsafe fn set_preempt_count(&self, count: usize) { 712 self.preempt_count.store(count, Ordering::SeqCst); 713 } 714 715 #[inline(always)] 716 pub fn flags(&self) -> &mut ProcessFlags { 717 return self.flags.get_mut(); 718 } 719 720 /// 请注意,这个值能在中断上下文中读取,但不能被中断上下文修改 721 /// 否则会导致死锁 722 #[inline(always)] 723 pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> { 724 return self.basic.read(); 725 } 726 727 #[inline(always)] 728 pub fn set_name(&self, name: String) { 729 self.basic.write().set_name(name); 730 } 731 732 #[inline(always)] 733 pub fn basic_mut(&self) -> RwLockWriteGuard<ProcessBasicInfo> { 734 return self.basic.write_irqsave(); 735 } 736 737 /// # 获取arch info的锁,同时关闭中断 738 #[inline(always)] 739 pub fn arch_info_irqsave(&self) -> SpinLockGuard<ArchPCBInfo> { 740 return self.arch_info.lock_irqsave(); 741 } 742 743 /// # 获取arch info的锁,但是不关闭中断 744 /// 745 /// 由于arch info在进程切换的时候会使用到, 746 /// 因此在中断上下文外,获取arch info 而不irqsave是不安全的. 747 /// 748 /// 只能在以下情况下使用这个函数: 749 /// - 在中断上下文中(中断已经禁用),获取arch info的锁。 750 /// - 刚刚创建新的pcb 751 #[inline(always)] 752 pub unsafe fn arch_info(&self) -> SpinLockGuard<ArchPCBInfo> { 753 return self.arch_info.lock(); 754 } 755 756 #[inline(always)] 757 pub fn kernel_stack(&self) -> RwLockReadGuard<KernelStack> { 758 return self.kernel_stack.read(); 759 } 760 761 #[inline(always)] 762 #[allow(dead_code)] 763 pub fn kernel_stack_mut(&self) -> RwLockWriteGuard<KernelStack> { 764 return self.kernel_stack.write(); 765 } 766 767 #[inline(always)] 768 pub fn sched_info(&self) -> &ProcessSchedulerInfo { 769 return &self.sched_info; 770 } 771 772 #[inline(always)] 773 pub fn worker_private(&self) -> SpinLockGuard<Option<WorkerPrivate>> { 774 return self.worker_private.lock(); 775 } 776 777 #[inline(always)] 778 pub fn pid(&self) -> Pid { 779 return self.pid; 780 } 781 782 #[inline(always)] 783 pub fn tgid(&self) -> Pid { 784 return self.tgid; 785 } 786 787 /// 获取文件描述符表的Arc指针 788 #[inline(always)] 789 pub fn fd_table(&self) -> Arc<RwLock<FileDescriptorVec>> { 790 return self.basic.read().fd_table().unwrap(); 791 } 792 793 /// 根据文件描述符序号,获取socket对象的Arc指针 794 /// 795 /// ## 参数 796 /// 797 /// - `fd` 文件描述符序号 798 /// 799 /// ## 返回值 800 /// 801 /// Option(&mut Box<dyn Socket>) socket对象的可变引用. 如果文件描述符不是socket,那么返回None 802 pub fn get_socket(&self, fd: i32) -> Option<Arc<SocketInode>> { 803 let binding = ProcessManager::current_pcb().fd_table(); 804 let fd_table_guard = binding.read(); 805 806 let f = fd_table_guard.get_file_by_fd(fd)?; 807 drop(fd_table_guard); 808 809 let guard = f.lock(); 810 if guard.file_type() != FileType::Socket { 811 return None; 812 } 813 let socket: Arc<SocketInode> = guard 814 .inode() 815 .downcast_arc::<SocketInode>() 816 .expect("Not a socket inode"); 817 return Some(socket); 818 } 819 820 /// 当前进程退出时,让初始进程收养所有子进程 821 unsafe fn adopt_childen(&self) -> Result<(), SystemError> { 822 match ProcessManager::find(Pid(1)) { 823 Some(init_pcb) => { 824 let childen_guard = self.children.write(); 825 let mut init_childen_guard = init_pcb.children.write(); 826 827 childen_guard.iter().for_each(|pid| { 828 init_childen_guard.push(*pid); 829 }); 830 831 return Ok(()); 832 } 833 _ => Err(SystemError::ECHILD), 834 } 835 } 836 837 /// 生成进程的名字 838 pub fn generate_name(program_path: &str, args: &Vec<String>) -> String { 839 let mut name = program_path.to_string(); 840 for arg in args { 841 name.push(' '); 842 name.push_str(arg); 843 } 844 return name; 845 } 846 847 pub fn sig_info(&self) -> RwLockReadGuard<ProcessSignalInfo> { 848 self.sig_info.read() 849 } 850 851 pub fn sig_info_irqsave(&self) -> RwLockReadGuard<ProcessSignalInfo> { 852 self.sig_info.read_irqsave() 853 } 854 855 pub fn try_siginfo(&self, times: u8) -> Option<RwLockReadGuard<ProcessSignalInfo>> { 856 for _ in 0..times { 857 if let Some(r) = self.sig_info.try_read() { 858 return Some(r); 859 } 860 } 861 862 return None; 863 } 864 865 pub fn sig_info_mut(&self) -> RwLockWriteGuard<ProcessSignalInfo> { 866 self.sig_info.write_irqsave() 867 } 868 869 pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> { 870 for _ in 0..times { 871 if let Some(r) = self.sig_info.try_write() { 872 return Some(r); 873 } 874 } 875 876 return None; 877 } 878 879 pub fn sig_struct(&self) -> SpinLockGuard<SignalStruct> { 880 self.sig_struct.lock() 881 } 882 883 pub fn try_sig_struct_irq(&self, times: u8) -> Option<SpinLockGuard<SignalStruct>> { 884 for _ in 0..times { 885 if let Ok(r) = self.sig_struct.try_lock_irqsave() { 886 return Some(r); 887 } 888 } 889 890 return None; 891 } 892 893 pub fn sig_struct_irqsave(&self) -> SpinLockGuard<SignalStruct> { 894 self.sig_struct.lock_irqsave() 895 } 896 } 897 898 impl Drop for ProcessControlBlock { 899 fn drop(&mut self) { 900 // 在ProcFS中,解除进程的注册 901 procfs_unregister_pid(self.pid()) 902 .unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}")); 903 904 if let Some(ppcb) = self.parent_pcb.read().upgrade() { 905 ppcb.children.write().retain(|pid| *pid != self.pid()); 906 } 907 } 908 } 909 910 /// 线程信息 911 #[derive(Debug)] 912 pub struct ThreadInfo { 913 // 来自用户空间记录用户线程id的地址,在该线程结束时将该地址置0以通知父进程 914 clear_child_tid: Option<VirtAddr>, 915 set_child_tid: Option<VirtAddr>, 916 917 vfork_done: Option<Arc<Completion>>, 918 /// 线程组的组长 919 group_leader: Weak<ProcessControlBlock>, 920 } 921 922 impl ThreadInfo { 923 pub fn new() -> Self { 924 Self { 925 clear_child_tid: None, 926 set_child_tid: None, 927 vfork_done: None, 928 group_leader: Weak::default(), 929 } 930 } 931 932 pub fn group_leader(&self) -> Option<Arc<ProcessControlBlock>> { 933 return self.group_leader.upgrade(); 934 } 935 } 936 937 /// 进程的基本信息 938 /// 939 /// 这个结构体保存进程的基本信息,主要是那些不会随着进程的运行而经常改变的信息。 940 #[derive(Debug)] 941 pub struct ProcessBasicInfo { 942 /// 当前进程的进程组id 943 pgid: Pid, 944 /// 当前进程的父进程的pid 945 ppid: Pid, 946 /// 进程的名字 947 name: String, 948 949 /// 当前进程的工作目录 950 cwd: String, 951 952 /// 用户地址空间 953 user_vm: Option<Arc<AddressSpace>>, 954 955 /// 文件描述符表 956 fd_table: Option<Arc<RwLock<FileDescriptorVec>>>, 957 } 958 959 impl ProcessBasicInfo { 960 #[inline(never)] 961 pub fn new( 962 pgid: Pid, 963 ppid: Pid, 964 name: String, 965 cwd: String, 966 user_vm: Option<Arc<AddressSpace>>, 967 ) -> RwLock<Self> { 968 let fd_table = Arc::new(RwLock::new(FileDescriptorVec::new())); 969 return RwLock::new(Self { 970 pgid, 971 ppid, 972 name, 973 cwd, 974 user_vm, 975 fd_table: Some(fd_table), 976 }); 977 } 978 979 pub fn pgid(&self) -> Pid { 980 return self.pgid; 981 } 982 983 pub fn ppid(&self) -> Pid { 984 return self.ppid; 985 } 986 987 pub fn name(&self) -> &str { 988 return &self.name; 989 } 990 991 pub fn set_name(&mut self, name: String) { 992 self.name = name; 993 } 994 995 pub fn cwd(&self) -> String { 996 return self.cwd.clone(); 997 } 998 pub fn set_cwd(&mut self, path: String) { 999 return self.cwd = path; 1000 } 1001 1002 pub fn user_vm(&self) -> Option<Arc<AddressSpace>> { 1003 return self.user_vm.clone(); 1004 } 1005 1006 pub unsafe fn set_user_vm(&mut self, user_vm: Option<Arc<AddressSpace>>) { 1007 self.user_vm = user_vm; 1008 } 1009 1010 pub fn fd_table(&self) -> Option<Arc<RwLock<FileDescriptorVec>>> { 1011 return self.fd_table.clone(); 1012 } 1013 1014 pub fn set_fd_table(&mut self, fd_table: Option<Arc<RwLock<FileDescriptorVec>>>) { 1015 self.fd_table = fd_table; 1016 } 1017 } 1018 1019 #[derive(Debug)] 1020 pub struct ProcessSchedulerInfo { 1021 /// 当前进程所在的cpu 1022 on_cpu: AtomicI32, 1023 /// 如果当前进程等待被迁移到另一个cpu核心上(也就是flags中的PF_NEED_MIGRATE被置位), 1024 /// 该字段存储要被迁移到的目标处理器核心号 1025 migrate_to: AtomicI32, 1026 inner_locked: RwLock<InnerSchedInfo>, 1027 /// 进程的调度优先级 1028 priority: SchedPriority, 1029 /// 当前进程的虚拟运行时间 1030 virtual_runtime: AtomicIsize, 1031 /// 由实时调度器管理的时间片 1032 rt_time_slice: AtomicIsize, 1033 } 1034 1035 #[derive(Debug)] 1036 pub struct InnerSchedInfo { 1037 /// 当前进程的状态 1038 state: ProcessState, 1039 /// 进程的调度策略 1040 sched_policy: SchedPolicy, 1041 } 1042 1043 impl InnerSchedInfo { 1044 pub fn state(&self) -> ProcessState { 1045 return self.state; 1046 } 1047 1048 pub fn set_state(&mut self, state: ProcessState) { 1049 self.state = state; 1050 } 1051 1052 pub fn policy(&self) -> SchedPolicy { 1053 return self.sched_policy; 1054 } 1055 } 1056 1057 impl ProcessSchedulerInfo { 1058 #[inline(never)] 1059 pub fn new(on_cpu: Option<u32>) -> Self { 1060 let cpu_id = match on_cpu { 1061 Some(cpu_id) => cpu_id as i32, 1062 None => -1, 1063 }; 1064 return Self { 1065 on_cpu: AtomicI32::new(cpu_id), 1066 migrate_to: AtomicI32::new(-1), 1067 inner_locked: RwLock::new(InnerSchedInfo { 1068 state: ProcessState::Blocked(false), 1069 sched_policy: SchedPolicy::CFS, 1070 }), 1071 virtual_runtime: AtomicIsize::new(0), 1072 rt_time_slice: AtomicIsize::new(0), 1073 priority: SchedPriority::new(100).unwrap(), 1074 }; 1075 } 1076 1077 pub fn on_cpu(&self) -> Option<u32> { 1078 let on_cpu = self.on_cpu.load(Ordering::SeqCst); 1079 if on_cpu == -1 { 1080 return None; 1081 } else { 1082 return Some(on_cpu as u32); 1083 } 1084 } 1085 1086 pub fn set_on_cpu(&self, on_cpu: Option<u32>) { 1087 if let Some(cpu_id) = on_cpu { 1088 self.on_cpu.store(cpu_id as i32, Ordering::SeqCst); 1089 } else { 1090 self.on_cpu.store(-1, Ordering::SeqCst); 1091 } 1092 } 1093 1094 pub fn migrate_to(&self) -> Option<u32> { 1095 let migrate_to = self.migrate_to.load(Ordering::SeqCst); 1096 if migrate_to == -1 { 1097 return None; 1098 } else { 1099 return Some(migrate_to as u32); 1100 } 1101 } 1102 1103 pub fn set_migrate_to(&self, migrate_to: Option<u32>) { 1104 if let Some(data) = migrate_to { 1105 self.migrate_to.store(data as i32, Ordering::SeqCst); 1106 } else { 1107 self.migrate_to.store(-1, Ordering::SeqCst) 1108 } 1109 } 1110 1111 pub fn inner_lock_write_irqsave(&self) -> RwLockWriteGuard<InnerSchedInfo> { 1112 return self.inner_locked.write_irqsave(); 1113 } 1114 1115 pub fn inner_lock_read_irqsave(&self) -> RwLockReadGuard<InnerSchedInfo> { 1116 return self.inner_locked.read_irqsave(); 1117 } 1118 1119 pub fn inner_lock_try_read_irqsave( 1120 &self, 1121 times: u8, 1122 ) -> Option<RwLockReadGuard<InnerSchedInfo>> { 1123 for _ in 0..times { 1124 if let Some(r) = self.inner_locked.try_read_irqsave() { 1125 return Some(r); 1126 } 1127 } 1128 1129 return None; 1130 } 1131 1132 pub fn inner_lock_try_upgradable_read_irqsave( 1133 &self, 1134 times: u8, 1135 ) -> Option<RwLockUpgradableGuard<InnerSchedInfo>> { 1136 for _ in 0..times { 1137 if let Some(r) = self.inner_locked.try_upgradeable_read_irqsave() { 1138 return Some(r); 1139 } 1140 } 1141 1142 return None; 1143 } 1144 1145 pub fn virtual_runtime(&self) -> isize { 1146 return self.virtual_runtime.load(Ordering::SeqCst); 1147 } 1148 1149 pub fn set_virtual_runtime(&self, virtual_runtime: isize) { 1150 self.virtual_runtime 1151 .store(virtual_runtime, Ordering::SeqCst); 1152 } 1153 pub fn increase_virtual_runtime(&self, delta: isize) { 1154 self.virtual_runtime.fetch_add(delta, Ordering::SeqCst); 1155 } 1156 1157 pub fn rt_time_slice(&self) -> isize { 1158 return self.rt_time_slice.load(Ordering::SeqCst); 1159 } 1160 1161 pub fn set_rt_time_slice(&self, rt_time_slice: isize) { 1162 self.rt_time_slice.store(rt_time_slice, Ordering::SeqCst); 1163 } 1164 1165 pub fn increase_rt_time_slice(&self, delta: isize) { 1166 self.rt_time_slice.fetch_add(delta, Ordering::SeqCst); 1167 } 1168 1169 pub fn priority(&self) -> SchedPriority { 1170 return self.priority; 1171 } 1172 } 1173 1174 #[derive(Debug, Clone)] 1175 pub struct KernelStack { 1176 stack: Option<AlignedBox<[u8; KernelStack::SIZE], { KernelStack::ALIGN }>>, 1177 /// 标记该内核栈是否可以被释放 1178 can_be_freed: bool, 1179 } 1180 1181 impl KernelStack { 1182 pub const SIZE: usize = 0x4000; 1183 pub const ALIGN: usize = 0x4000; 1184 1185 pub fn new() -> Result<Self, SystemError> { 1186 return Ok(Self { 1187 stack: Some( 1188 AlignedBox::<[u8; KernelStack::SIZE], { KernelStack::ALIGN }>::new_zeroed()?, 1189 ), 1190 can_be_freed: true, 1191 }); 1192 } 1193 1194 /// 根据已有的空间,构造一个内核栈结构体 1195 /// 1196 /// 仅仅用于BSP启动时,为idle进程构造内核栈。其他时候使用这个函数,很可能造成错误! 1197 pub unsafe fn from_existed(base: VirtAddr) -> Result<Self, SystemError> { 1198 if base.is_null() || base.check_aligned(Self::ALIGN) == false { 1199 return Err(SystemError::EFAULT); 1200 } 1201 1202 return Ok(Self { 1203 stack: Some( 1204 AlignedBox::<[u8; KernelStack::SIZE], { KernelStack::ALIGN }>::new_unchecked( 1205 base.data() as *mut [u8; KernelStack::SIZE], 1206 ), 1207 ), 1208 can_be_freed: false, 1209 }); 1210 } 1211 1212 /// 返回内核栈的起始虚拟地址(低地址) 1213 pub fn start_address(&self) -> VirtAddr { 1214 return VirtAddr::new(self.stack.as_ref().unwrap().as_ptr() as usize); 1215 } 1216 1217 /// 返回内核栈的结束虚拟地址(高地址)(不包含该地址) 1218 pub fn stack_max_address(&self) -> VirtAddr { 1219 return VirtAddr::new(self.stack.as_ref().unwrap().as_ptr() as usize + Self::SIZE); 1220 } 1221 1222 pub unsafe fn set_pcb(&mut self, pcb: Weak<ProcessControlBlock>) -> Result<(), SystemError> { 1223 // 将一个Weak<ProcessControlBlock>放到内核栈的最低地址处 1224 let p: *const ProcessControlBlock = Weak::into_raw(pcb); 1225 let stack_bottom_ptr = self.start_address().data() as *mut *const ProcessControlBlock; 1226 1227 // 如果内核栈的最低地址处已经有了一个pcb,那么,这里就不再设置,直接返回错误 1228 if unlikely(unsafe { !(*stack_bottom_ptr).is_null() }) { 1229 kerror!("kernel stack bottom is not null: {:p}", *stack_bottom_ptr); 1230 return Err(SystemError::EPERM); 1231 } 1232 // 将pcb的地址放到内核栈的最低地址处 1233 unsafe { 1234 *stack_bottom_ptr = p; 1235 } 1236 1237 return Ok(()); 1238 } 1239 1240 /// 清除内核栈的pcb指针 1241 /// 1242 /// ## 参数 1243 /// 1244 /// - `force` : 如果为true,那么,即使该内核栈的pcb指针不为null,也会被强制清除而不处理Weak指针问题 1245 pub unsafe fn clear_pcb(&mut self, force: bool) { 1246 let stack_bottom_ptr = self.start_address().data() as *mut *const ProcessControlBlock; 1247 if unlikely(unsafe { (*stack_bottom_ptr).is_null() }) { 1248 return; 1249 } 1250 1251 if !force { 1252 let pcb_ptr: Weak<ProcessControlBlock> = Weak::from_raw(*stack_bottom_ptr); 1253 drop(pcb_ptr); 1254 } 1255 1256 *stack_bottom_ptr = core::ptr::null(); 1257 } 1258 1259 /// 返回指向当前内核栈pcb的Arc指针 1260 #[allow(dead_code)] 1261 pub unsafe fn pcb(&self) -> Option<Arc<ProcessControlBlock>> { 1262 // 从内核栈的最低地址处取出pcb的地址 1263 let p = self.stack.as_ref().unwrap().as_ptr() as *const *const ProcessControlBlock; 1264 if unlikely(unsafe { (*p).is_null() }) { 1265 return None; 1266 } 1267 1268 // 为了防止内核栈的pcb指针被释放,这里需要将其包装一下,使得Arc的drop不会被调用 1269 let weak_wrapper: ManuallyDrop<Weak<ProcessControlBlock>> = 1270 ManuallyDrop::new(Weak::from_raw(*p)); 1271 1272 let new_arc: Arc<ProcessControlBlock> = weak_wrapper.upgrade()?; 1273 return Some(new_arc); 1274 } 1275 } 1276 1277 impl Drop for KernelStack { 1278 fn drop(&mut self) { 1279 if !self.stack.is_none() { 1280 let ptr = self.stack.as_ref().unwrap().as_ptr() as *const *const ProcessControlBlock; 1281 if unsafe { !(*ptr).is_null() } { 1282 let pcb_ptr: Weak<ProcessControlBlock> = unsafe { Weak::from_raw(*ptr) }; 1283 drop(pcb_ptr); 1284 } 1285 } 1286 // 如果该内核栈不可以被释放,那么,这里就forget,不调用AlignedBox的drop函数 1287 if !self.can_be_freed { 1288 let bx = self.stack.take(); 1289 core::mem::forget(bx); 1290 } 1291 } 1292 } 1293 1294 pub fn process_init() { 1295 ProcessManager::init(); 1296 } 1297 1298 #[derive(Debug)] 1299 pub struct ProcessSignalInfo { 1300 // 当前进程 1301 sig_block: SigSet, 1302 // sig_pending 中存储当前线程要处理的信号 1303 sig_pending: SigPending, 1304 // sig_shared_pending 中存储当前线程所属进程要处理的信号 1305 sig_shared_pending: SigPending, 1306 // 当前进程对应的tty 1307 tty: Option<Arc<TtyCore>>, 1308 } 1309 1310 impl ProcessSignalInfo { 1311 pub fn sig_block(&self) -> &SigSet { 1312 &self.sig_block 1313 } 1314 1315 pub fn sig_pending(&self) -> &SigPending { 1316 &self.sig_pending 1317 } 1318 1319 pub fn sig_pending_mut(&mut self) -> &mut SigPending { 1320 &mut self.sig_pending 1321 } 1322 1323 pub fn sig_block_mut(&mut self) -> &mut SigSet { 1324 &mut self.sig_block 1325 } 1326 1327 pub fn sig_shared_pending_mut(&mut self) -> &mut SigPending { 1328 &mut self.sig_shared_pending 1329 } 1330 1331 pub fn sig_shared_pending(&self) -> &SigPending { 1332 &self.sig_shared_pending 1333 } 1334 1335 pub fn tty(&self) -> Option<Arc<TtyCore>> { 1336 self.tty.clone() 1337 } 1338 1339 pub fn set_tty(&mut self, tty: Arc<TtyCore>) { 1340 self.tty = Some(tty); 1341 } 1342 1343 /// 从 pcb 的 siginfo中取出下一个要处理的信号,先处理线程信号,再处理进程信号 1344 /// 1345 /// ## 参数 1346 /// 1347 /// - `sig_mask` 被忽略掉的信号 1348 /// 1349 pub fn dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>) { 1350 let res = self.sig_pending.dequeue_signal(sig_mask); 1351 if res.0 != Signal::INVALID { 1352 return res; 1353 } else { 1354 return self.sig_shared_pending.dequeue_signal(sig_mask); 1355 } 1356 } 1357 } 1358 1359 impl Default for ProcessSignalInfo { 1360 fn default() -> Self { 1361 Self { 1362 sig_block: SigSet::empty(), 1363 sig_pending: SigPending::default(), 1364 sig_shared_pending: SigPending::default(), 1365 tty: None, 1366 } 1367 } 1368 } 1369