1 use core::{ 2 hash::{Hash, Hasher}, 3 intrinsics::{likely, unlikely}, 4 mem::ManuallyDrop, 5 sync::atomic::{compiler_fence, AtomicBool, AtomicI32, AtomicIsize, AtomicUsize, Ordering}, 6 }; 7 8 use alloc::{ 9 string::{String, ToString}, 10 sync::{Arc, Weak}, 11 vec::Vec, 12 }; 13 use hashbrown::HashMap; 14 15 use crate::{ 16 arch::{process::ArchPCBInfo, sched::sched, CurrentIrqArch}, 17 exception::InterruptArch, 18 filesystem::{ 19 procfs::procfs_unregister_pid, 20 vfs::{file::FileDescriptorVec, FileType}, 21 }, 22 kdebug, kinfo, 23 libs::{ 24 align::AlignedBox, 25 casting::DowncastArc, 26 rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, 27 spinlock::{SpinLock, SpinLockGuard}, 28 wait_queue::WaitQueue, 29 }, 30 mm::{percpu::PerCpuVar, set_INITIAL_PROCESS_ADDRESS_SPACE, ucontext::AddressSpace, VirtAddr}, 31 net::socket::SocketInode, 32 sched::{ 33 core::{sched_enqueue, CPU_EXECUTING}, 34 SchedPolicy, SchedPriority, 35 }, 36 smp::kick_cpu, 37 syscall::SystemError, 38 }; 39 40 use self::kthread::WorkerPrivate; 41 42 pub mod abi; 43 pub mod c_adapter; 44 pub mod exec; 45 pub mod fork; 46 pub mod idle; 47 pub mod init; 48 pub mod kthread; 49 pub mod process; 50 pub mod syscall; 51 52 /// 系统中所有进程的pcb 53 static ALL_PROCESS: SpinLock<Option<HashMap<Pid, Arc<ProcessControlBlock>>>> = SpinLock::new(None); 54 55 pub static mut SWITCH_RESULT: Option<PerCpuVar<SwitchResult>> = None; 56 57 /// 一个只改变1次的全局变量,标志进程管理器是否已经初始化完成 58 static mut __PROCESS_MANAGEMENT_INIT_DONE: bool = false; 59 60 #[derive(Debug)] 61 pub struct SwitchResult { 62 pub prev_pcb: Option<Arc<ProcessControlBlock>>, 63 pub next_pcb: Option<Arc<ProcessControlBlock>>, 64 } 65 66 impl SwitchResult { 67 pub fn new() -> Self { 68 Self { 69 prev_pcb: None, 70 next_pcb: None, 71 } 72 } 73 } 74 75 #[derive(Debug)] 76 pub struct ProcessManager; 77 impl ProcessManager { 78 fn init() { 79 static INIT_FLAG: AtomicBool = AtomicBool::new(false); 80 if INIT_FLAG 81 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 82 .is_err() 83 { 84 panic!("ProcessManager has been initialized!"); 85 } 86 87 unsafe { 88 compiler_fence(Ordering::SeqCst); 89 kdebug!("To create address space for INIT process."); 90 // test_buddy(); 91 set_INITIAL_PROCESS_ADDRESS_SPACE( 92 AddressSpace::new(true).expect("Failed to create address space for INIT process."), 93 ); 94 kdebug!("INIT process address space created."); 95 compiler_fence(Ordering::SeqCst); 96 }; 97 98 ALL_PROCESS.lock().replace(HashMap::new()); 99 Self::arch_init(); 100 kdebug!("process arch init done."); 101 Self::init_idle(); 102 kdebug!("process idle init done."); 103 104 unsafe { 105 __PROCESS_MANAGEMENT_INIT_DONE = true; 106 } 107 kinfo!("Process Manager initialized."); 108 } 109 110 /// 获取当前进程的pcb 111 pub fn current_pcb() -> Arc<ProcessControlBlock> { 112 return ProcessControlBlock::arch_current_pcb(); 113 } 114 115 /// 增加当前进程的锁持有计数 116 #[inline(always)] 117 pub fn preempt_disable() { 118 if likely(unsafe { __PROCESS_MANAGEMENT_INIT_DONE }) { 119 ProcessManager::current_pcb().preempt_disable(); 120 } 121 } 122 123 /// 减少当前进程的锁持有计数 124 #[inline(always)] 125 pub fn preempt_enable() { 126 if likely(unsafe { __PROCESS_MANAGEMENT_INIT_DONE }) { 127 ProcessManager::current_pcb().preempt_enable(); 128 } 129 } 130 131 /// 根据pid获取进程的pcb 132 /// 133 /// ## 参数 134 /// 135 /// - `pid` : 进程的pid 136 /// 137 /// ## 返回值 138 /// 139 /// 如果找到了对应的进程,那么返回该进程的pcb,否则返回None 140 pub fn find(pid: Pid) -> Option<Arc<ProcessControlBlock>> { 141 return ALL_PROCESS.lock().as_ref()?.get(&pid).cloned(); 142 } 143 144 /// 向系统中添加一个进程的pcb 145 /// 146 /// ## 参数 147 /// 148 /// - `pcb` : 进程的pcb 149 /// 150 /// ## 返回值 151 /// 152 /// 无 153 pub fn add_pcb(pcb: Arc<ProcessControlBlock>) { 154 ALL_PROCESS 155 .lock() 156 .as_mut() 157 .unwrap() 158 .insert(pcb.pid(), pcb.clone()); 159 } 160 161 /// 唤醒一个进程 162 pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> { 163 let state = pcb.sched_info().state(); 164 if state.is_blocked() { 165 let mut writer = pcb.sched_info_mut(); 166 let state = writer.state(); 167 if state.is_blocked() { 168 writer.set_state(ProcessState::Runnable); 169 // avoid deadlock 170 drop(writer); 171 172 sched_enqueue(pcb.clone(), true); 173 return Ok(()); 174 } else if state.is_exited() { 175 return Err(SystemError::EINVAL); 176 } else { 177 return Ok(()); 178 } 179 } else if state.is_exited() { 180 return Err(SystemError::EINVAL); 181 } else { 182 return Ok(()); 183 } 184 } 185 186 /// 标志当前进程永久睡眠,但是发起调度的工作,应该由调用者完成 187 /// 188 /// ## 注意 189 /// 190 /// - 进入当前函数之前,不能持有sched_info的锁 191 /// - 进入当前函数之前,必须关闭中断 192 pub fn mark_sleep(interruptable: bool) -> Result<(), SystemError> { 193 assert_eq!( 194 CurrentIrqArch::is_irq_enabled(), 195 false, 196 "interrupt must be disabled before enter ProcessManager::mark_sleep()" 197 ); 198 199 let pcb = ProcessManager::current_pcb(); 200 let mut writer = pcb.sched_info_mut_irqsave(); 201 if writer.state() != ProcessState::Exited(0) { 202 writer.set_state(ProcessState::Blocked(interruptable)); 203 pcb.flags().insert(ProcessFlags::NEED_SCHEDULE); 204 drop(writer); 205 206 return Ok(()); 207 } 208 return Err(SystemError::EINTR); 209 } 210 211 /// 当子进程退出后向父进程发送通知 212 fn exit_notify() { 213 let current = ProcessManager::current_pcb(); 214 // 让INIT进程收养所有子进程 215 if current.pid() != Pid(1) { 216 unsafe { 217 current 218 .adopt_childen() 219 .unwrap_or_else(|e| panic!("adopte_childen failed: error: {e:?}")) 220 }; 221 // todo: 当信号机制重写后,这里需要向父进程发送SIGCHLD信号 222 } 223 } 224 225 /// 退出当前进程 226 /// 227 /// ## 参数 228 /// 229 /// - `exit_code` : 进程的退出码 230 pub fn exit(exit_code: usize) -> ! { 231 // 关中断 232 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 233 let pcb = ProcessManager::current_pcb(); 234 pcb.sched_info 235 .write() 236 .set_state(ProcessState::Exited(exit_code)); 237 pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true))); 238 drop(pcb); 239 ProcessManager::exit_notify(); 240 drop(irq_guard); 241 sched(); 242 loop {} 243 } 244 245 pub unsafe fn release(pid: Pid) { 246 let pcb = ProcessManager::find(pid); 247 if !pcb.is_none() { 248 let pcb = pcb.unwrap(); 249 // 判断该pcb是否在全局没有任何引用 250 if Arc::strong_count(&pcb) <= 1 { 251 drop(pcb); 252 ALL_PROCESS.lock().as_mut().unwrap().remove(&pid); 253 } else { 254 // 如果不为1就panic 255 panic!("pcb is still referenced"); 256 } 257 } 258 } 259 260 /// 上下文切换完成后的钩子函数 261 unsafe fn switch_finish_hook() { 262 // kdebug!("switch_finish_hook"); 263 let prev_pcb = SWITCH_RESULT 264 .as_mut() 265 .unwrap() 266 .get_mut() 267 .prev_pcb 268 .take() 269 .expect("prev_pcb is None"); 270 let next_pcb = SWITCH_RESULT 271 .as_mut() 272 .unwrap() 273 .get_mut() 274 .next_pcb 275 .take() 276 .expect("next_pcb is None"); 277 278 // 由于进程切换前使用了SpinLockGuard::leak(),所以这里需要手动释放锁 279 prev_pcb.arch_info.force_unlock(); 280 next_pcb.arch_info.force_unlock(); 281 } 282 283 /// 如果目标进程正在目标CPU上运行,那么就让这个cpu陷入内核态 284 /// 285 /// ## 参数 286 /// 287 /// - `pcb` : 进程的pcb 288 #[allow(dead_code)] 289 pub fn kick(pcb: &Arc<ProcessControlBlock>) { 290 ProcessManager::current_pcb().preempt_disable(); 291 let cpu_id = pcb.sched_info().on_cpu(); 292 293 if let Some(cpu_id) = cpu_id { 294 let cpu_id = cpu_id; 295 296 if pcb.pid() == CPU_EXECUTING.get(cpu_id) { 297 kick_cpu(cpu_id).expect("ProcessManager::kick(): Failed to kick cpu"); 298 } 299 } 300 301 ProcessManager::current_pcb().preempt_enable(); 302 } 303 } 304 305 /// 上下文切换的钩子函数,当这个函数return的时候,将会发生上下文切换 306 pub unsafe extern "sysv64" fn switch_finish_hook() { 307 ProcessManager::switch_finish_hook(); 308 } 309 310 int_like!(Pid, AtomicPid, usize, AtomicUsize); 311 312 impl Hash for Pid { 313 fn hash<H: Hasher>(&self, state: &mut H) { 314 self.0.hash(state); 315 } 316 } 317 318 impl Pid { 319 pub fn to_string(&self) -> String { 320 self.0.to_string() 321 } 322 } 323 324 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 325 pub enum ProcessState { 326 /// The process is running on a CPU or in a run queue. 327 Runnable, 328 /// The process is waiting for an event to occur. 329 /// 其中的bool表示该等待过程是否可以被打断。 330 /// - 如果该bool为true,那么,硬件中断/信号/其他系统事件都可以打断该等待过程,使得该进程重新进入Runnable状态。 331 /// - 如果该bool为false,那么,这个进程必须被显式的唤醒,才能重新进入Runnable状态。 332 Blocked(bool), 333 /// 进程被信号终止 334 // Stopped(SignalNumber), 335 /// 进程已经退出,usize表示进程的退出码 336 Exited(usize), 337 } 338 339 #[allow(dead_code)] 340 impl ProcessState { 341 #[inline(always)] 342 pub fn is_runnable(&self) -> bool { 343 return matches!(self, ProcessState::Runnable); 344 } 345 346 #[inline(always)] 347 pub fn is_blocked(&self) -> bool { 348 return matches!(self, ProcessState::Blocked(_)); 349 } 350 351 #[inline(always)] 352 pub fn is_exited(&self) -> bool { 353 return matches!(self, ProcessState::Exited(_)); 354 } 355 } 356 357 bitflags! { 358 /// pcb的标志位 359 pub struct ProcessFlags: usize { 360 /// 当前pcb表示一个内核线程 361 const KTHREAD = 1 << 0; 362 /// 当前进程需要被调度 363 const NEED_SCHEDULE = 1 << 1; 364 /// 进程由于vfork而与父进程存在资源共享 365 const VFORK = 1 << 2; 366 /// 进程不可被冻结 367 const NOFREEZE = 1 << 3; 368 /// 进程正在退出 369 const EXITING = 1 << 4; 370 /// 进程由于接收到终止信号唤醒 371 const WAKEKILL = 1 << 5; 372 /// 进程由于接收到信号而退出.(Killed by a signal) 373 const SIGNALED = 1 << 6; 374 /// 进程需要迁移到其他cpu上 375 const NEED_MIGRATE = 1 << 7; 376 } 377 } 378 379 #[derive(Debug)] 380 pub struct ProcessControlBlock { 381 /// 当前进程的pid 382 pid: Pid, 383 384 basic: RwLock<ProcessBasicInfo>, 385 /// 当前进程的自旋锁持有计数 386 preempt_count: AtomicUsize, 387 388 flags: SpinLock<ProcessFlags>, 389 worker_private: SpinLock<Option<WorkerPrivate>>, 390 /// 进程的内核栈 391 kernel_stack: RwLock<KernelStack>, 392 393 /// 与调度相关的信息 394 sched_info: RwLock<ProcessSchedulerInfo>, 395 /// 与处理器架构相关的信息 396 arch_info: SpinLock<ArchPCBInfo>, 397 398 /// 父进程指针 399 parent_pcb: RwLock<Weak<ProcessControlBlock>>, 400 401 /// 子进程链表 402 children: RwLock<HashMap<Pid, Arc<ProcessControlBlock>>>, 403 404 /// 等待队列 405 wait_queue: WaitQueue, 406 } 407 408 impl ProcessControlBlock { 409 /// Generate a new pcb. 410 /// 411 /// ## 参数 412 /// 413 /// - `name` : 进程的名字 414 /// - `kstack` : 进程的内核栈 415 /// 416 /// ## 返回值 417 /// 418 /// 返回一个新的pcb 419 pub fn new(name: String, kstack: KernelStack) -> Arc<Self> { 420 return Self::do_create_pcb(name, kstack, false); 421 } 422 423 /// 创建一个新的idle进程 424 /// 425 /// 请注意,这个函数只能在进程管理初始化的时候调用。 426 pub fn new_idle(cpu_id: u32, kstack: KernelStack) -> Arc<Self> { 427 let name = format!("idle-{}", cpu_id); 428 return Self::do_create_pcb(name, kstack, true); 429 } 430 431 fn do_create_pcb(name: String, kstack: KernelStack, is_idle: bool) -> Arc<Self> { 432 let (pid, ppid, cwd) = if is_idle { 433 (Pid(0), Pid(0), "/".to_string()) 434 } else { 435 ( 436 Self::generate_pid(), 437 ProcessManager::current_pcb().pid(), 438 ProcessManager::current_pcb().basic().cwd(), 439 ) 440 }; 441 442 let basic_info = ProcessBasicInfo::new(Pid(0), ppid, name, cwd, None); 443 let preempt_count = AtomicUsize::new(0); 444 let flags = SpinLock::new(ProcessFlags::empty()); 445 446 let sched_info = ProcessSchedulerInfo::new(None); 447 let arch_info = SpinLock::new(ArchPCBInfo::new(Some(&kstack))); 448 449 let ppcb: Weak<ProcessControlBlock> = ProcessManager::find(ppid) 450 .map(|p| Arc::downgrade(&p)) 451 .unwrap_or_else(|| Weak::new()); 452 453 let pcb = Self { 454 pid, 455 basic: basic_info, 456 preempt_count, 457 flags, 458 kernel_stack: RwLock::new(kstack), 459 worker_private: SpinLock::new(None), 460 sched_info, 461 arch_info, 462 parent_pcb: RwLock::new(ppcb), 463 children: RwLock::new(HashMap::new()), 464 wait_queue: WaitQueue::INIT, 465 }; 466 467 let pcb = Arc::new(pcb); 468 469 // 设置进程的arc指针到内核栈的最低地址处 470 unsafe { pcb.kernel_stack.write().set_pcb(Arc::clone(&pcb)).unwrap() }; 471 472 // 将当前pcb加入父进程的子进程哈希表中 473 if pcb.pid() > Pid(1) { 474 if let Some(ppcb_arc) = pcb.parent_pcb.read().upgrade() { 475 let mut children = ppcb_arc.children.write(); 476 children.insert(pcb.pid(), pcb.clone()); 477 } else { 478 panic!("parent pcb is None"); 479 } 480 } 481 482 return pcb; 483 } 484 485 /// 生成一个新的pid 486 #[inline(always)] 487 fn generate_pid() -> Pid { 488 static NEXT_PID: AtomicPid = AtomicPid::new(Pid(1)); 489 return NEXT_PID.fetch_add(Pid(1), Ordering::SeqCst); 490 } 491 492 /// 返回当前进程的锁持有计数 493 #[inline(always)] 494 pub fn preempt_count(&self) -> usize { 495 return self.preempt_count.load(Ordering::SeqCst); 496 } 497 498 /// 增加当前进程的锁持有计数 499 #[inline(always)] 500 pub fn preempt_disable(&self) { 501 self.preempt_count.fetch_add(1, Ordering::SeqCst); 502 } 503 504 /// 减少当前进程的锁持有计数 505 #[inline(always)] 506 pub fn preempt_enable(&self) { 507 self.preempt_count.fetch_sub(1, Ordering::SeqCst); 508 } 509 510 #[inline(always)] 511 pub unsafe fn set_preempt_count(&self, count: usize) { 512 self.preempt_count.store(count, Ordering::SeqCst); 513 } 514 515 #[inline(always)] 516 pub fn flags(&self) -> SpinLockGuard<ProcessFlags> { 517 return self.flags.lock(); 518 } 519 520 #[inline(always)] 521 pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> { 522 return self.basic.read(); 523 } 524 525 #[inline(always)] 526 pub fn set_name(&self, name: String) { 527 self.basic.write().set_name(name); 528 } 529 530 #[inline(always)] 531 pub fn basic_mut(&self) -> RwLockWriteGuard<ProcessBasicInfo> { 532 return self.basic.write(); 533 } 534 535 #[inline(always)] 536 pub fn arch_info(&self) -> SpinLockGuard<ArchPCBInfo> { 537 return self.arch_info.lock(); 538 } 539 540 #[inline(always)] 541 pub fn arch_info_irqsave(&self) -> SpinLockGuard<ArchPCBInfo> { 542 return self.arch_info.lock_irqsave(); 543 } 544 545 #[inline(always)] 546 pub fn kernel_stack(&self) -> RwLockReadGuard<KernelStack> { 547 return self.kernel_stack.read(); 548 } 549 550 #[inline(always)] 551 #[allow(dead_code)] 552 pub fn kernel_stack_mut(&self) -> RwLockWriteGuard<KernelStack> { 553 return self.kernel_stack.write(); 554 } 555 556 #[inline(always)] 557 pub fn sched_info(&self) -> RwLockReadGuard<ProcessSchedulerInfo> { 558 return self.sched_info.read(); 559 } 560 561 #[inline(always)] 562 pub fn sched_info_mut(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> { 563 return self.sched_info.write(); 564 } 565 566 #[inline(always)] 567 pub fn sched_info_mut_irqsave(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> { 568 return self.sched_info.write_irqsave(); 569 } 570 571 #[inline(always)] 572 pub fn worker_private(&self) -> SpinLockGuard<Option<WorkerPrivate>> { 573 return self.worker_private.lock(); 574 } 575 576 #[inline(always)] 577 pub fn pid(&self) -> Pid { 578 return self.pid; 579 } 580 581 /// 获取文件描述符表的Arc指针 582 #[inline(always)] 583 pub fn fd_table(&self) -> Arc<RwLock<FileDescriptorVec>> { 584 return self.basic.read().fd_table().unwrap(); 585 } 586 587 /// 根据文件描述符序号,获取socket对象的Arc指针 588 /// 589 /// ## 参数 590 /// 591 /// - `fd` 文件描述符序号 592 /// 593 /// ## 返回值 594 /// 595 /// Option(&mut Box<dyn Socket>) socket对象的可变引用. 如果文件描述符不是socket,那么返回None 596 pub fn get_socket(&self, fd: i32) -> Option<Arc<SocketInode>> { 597 let binding = ProcessManager::current_pcb().fd_table(); 598 let fd_table_guard = binding.read(); 599 600 let f = fd_table_guard.get_file_by_fd(fd)?; 601 drop(fd_table_guard); 602 603 let guard = f.lock(); 604 if guard.file_type() != FileType::Socket { 605 return None; 606 } 607 let socket: Arc<SocketInode> = guard 608 .inode() 609 .downcast_arc::<SocketInode>() 610 .expect("Not a socket inode"); 611 return Some(socket); 612 } 613 614 /// 当前进程退出时,让初始进程收养所有子进程 615 unsafe fn adopt_childen(&self) -> Result<(), SystemError> { 616 match ProcessManager::find(Pid(1)) { 617 Some(init_pcb) => { 618 let mut childen_guard = self.children.write(); 619 let mut init_childen_guard = init_pcb.children.write(); 620 621 childen_guard.drain().for_each(|(pid, child)| { 622 init_childen_guard.insert(pid, child); 623 }); 624 625 return Ok(()); 626 } 627 _ => Err(SystemError::ECHILD), 628 } 629 } 630 631 /// 生成进程的名字 632 pub fn generate_name(_program_path: &str, args: &Vec<String>) -> String { 633 let mut name = "".to_string(); 634 for arg in args { 635 name.push_str(arg); 636 name.push(' '); 637 } 638 return name; 639 } 640 } 641 642 impl Drop for ProcessControlBlock { 643 fn drop(&mut self) { 644 // 在ProcFS中,解除进程的注册 645 procfs_unregister_pid(self.pid()) 646 .unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}")); 647 648 if let Some(ppcb) = self.parent_pcb.read().upgrade() { 649 ppcb.children.write().remove(&self.pid()); 650 } 651 652 unsafe { ProcessManager::release(self.pid()) }; 653 } 654 } 655 /// 进程的基本信息 656 /// 657 /// 这个结构体保存进程的基本信息,主要是那些不会随着进程的运行而经常改变的信息。 658 #[derive(Debug)] 659 pub struct ProcessBasicInfo { 660 /// 当前进程的进程组id 661 pgid: Pid, 662 /// 当前进程的父进程的pid 663 ppid: Pid, 664 /// 进程的名字 665 name: String, 666 667 /// 当前进程的工作目录 668 cwd: String, 669 670 /// 用户地址空间 671 user_vm: Option<Arc<AddressSpace>>, 672 673 /// 文件描述符表 674 fd_table: Option<Arc<RwLock<FileDescriptorVec>>>, 675 } 676 677 impl ProcessBasicInfo { 678 pub fn new( 679 pgid: Pid, 680 ppid: Pid, 681 name: String, 682 cwd: String, 683 user_vm: Option<Arc<AddressSpace>>, 684 ) -> RwLock<Self> { 685 let fd_table = Arc::new(RwLock::new(FileDescriptorVec::new())); 686 return RwLock::new(Self { 687 pgid, 688 ppid, 689 name, 690 cwd, 691 user_vm, 692 fd_table: Some(fd_table), 693 }); 694 } 695 696 pub fn pgid(&self) -> Pid { 697 return self.pgid; 698 } 699 700 pub fn ppid(&self) -> Pid { 701 return self.ppid; 702 } 703 704 pub fn name(&self) -> &str { 705 return &self.name; 706 } 707 708 pub fn set_name(&mut self, name: String) { 709 self.name = name; 710 } 711 712 pub fn cwd(&self) -> String { 713 return self.cwd.clone(); 714 } 715 pub fn set_cwd(&mut self, path: String) { 716 return self.cwd = path; 717 } 718 719 pub fn user_vm(&self) -> Option<Arc<AddressSpace>> { 720 return self.user_vm.clone(); 721 } 722 723 pub unsafe fn set_user_vm(&mut self, user_vm: Option<Arc<AddressSpace>>) { 724 self.user_vm = user_vm; 725 } 726 727 pub fn fd_table(&self) -> Option<Arc<RwLock<FileDescriptorVec>>> { 728 return self.fd_table.clone(); 729 } 730 731 pub fn set_fd_table(&mut self, fd_table: Option<Arc<RwLock<FileDescriptorVec>>>) { 732 self.fd_table = fd_table; 733 } 734 } 735 736 #[derive(Debug)] 737 pub struct ProcessSchedulerInfo { 738 /// 当前进程所在的cpu 739 on_cpu: AtomicI32, 740 /// 如果当前进程等待被迁移到另一个cpu核心上(也就是flags中的PF_NEED_MIGRATE被置位), 741 /// 该字段存储要被迁移到的目标处理器核心号 742 migrate_to: AtomicI32, 743 744 /// 当前进程的状态 745 state: ProcessState, 746 /// 进程的调度策略 747 sched_policy: SchedPolicy, 748 /// 进程的调度优先级 749 priority: SchedPriority, 750 /// 当前进程的虚拟运行时间 751 virtual_runtime: AtomicIsize, 752 /// 由实时调度器管理的时间片 753 rt_time_slice: AtomicIsize, 754 } 755 756 impl ProcessSchedulerInfo { 757 pub fn new(on_cpu: Option<u32>) -> RwLock<Self> { 758 let cpu_id = match on_cpu { 759 Some(cpu_id) => cpu_id as i32, 760 None => -1, 761 }; 762 return RwLock::new(Self { 763 on_cpu: AtomicI32::new(cpu_id), 764 migrate_to: AtomicI32::new(-1), 765 state: ProcessState::Blocked(false), 766 sched_policy: SchedPolicy::CFS, 767 virtual_runtime: AtomicIsize::new(0), 768 rt_time_slice: AtomicIsize::new(0), 769 priority: SchedPriority::new(100).unwrap(), 770 }); 771 } 772 773 pub fn on_cpu(&self) -> Option<u32> { 774 let on_cpu = self.on_cpu.load(Ordering::SeqCst); 775 if on_cpu == -1 { 776 return None; 777 } else { 778 return Some(on_cpu as u32); 779 } 780 } 781 782 pub fn set_on_cpu(&self, on_cpu: Option<u32>) { 783 if let Some(cpu_id) = on_cpu { 784 self.on_cpu.store(cpu_id as i32, Ordering::SeqCst); 785 } else { 786 self.on_cpu.store(-1, Ordering::SeqCst); 787 } 788 } 789 790 pub fn migrate_to(&self) -> Option<u32> { 791 let migrate_to = self.migrate_to.load(Ordering::SeqCst); 792 if migrate_to == -1 { 793 return None; 794 } else { 795 return Some(migrate_to as u32); 796 } 797 } 798 799 pub fn set_migrate_to(&self, migrate_to: Option<u32>) { 800 if let Some(data) = migrate_to { 801 self.migrate_to.store(data as i32, Ordering::SeqCst); 802 } else { 803 self.migrate_to.store(-1, Ordering::SeqCst) 804 } 805 } 806 807 pub fn state(&self) -> ProcessState { 808 return self.state; 809 } 810 811 fn set_state(&mut self, state: ProcessState) { 812 self.state = state; 813 } 814 815 pub fn policy(&self) -> SchedPolicy { 816 return self.sched_policy; 817 } 818 819 pub fn virtual_runtime(&self) -> isize { 820 return self.virtual_runtime.load(Ordering::SeqCst); 821 } 822 823 pub fn set_virtual_runtime(&self, virtual_runtime: isize) { 824 self.virtual_runtime 825 .store(virtual_runtime, Ordering::SeqCst); 826 } 827 pub fn increase_virtual_runtime(&self, delta: isize) { 828 self.virtual_runtime.fetch_add(delta, Ordering::SeqCst); 829 } 830 831 pub fn rt_time_slice(&self) -> isize { 832 return self.rt_time_slice.load(Ordering::SeqCst); 833 } 834 835 pub fn set_rt_time_slice(&self, rt_time_slice: isize) { 836 self.rt_time_slice.store(rt_time_slice, Ordering::SeqCst); 837 } 838 839 pub fn increase_rt_time_slice(&self, delta: isize) { 840 self.rt_time_slice.fetch_add(delta, Ordering::SeqCst); 841 } 842 843 pub fn priority(&self) -> SchedPriority { 844 return self.priority; 845 } 846 } 847 848 #[derive(Debug)] 849 pub struct KernelStack { 850 stack: Option<AlignedBox<[u8; KernelStack::SIZE], { KernelStack::ALIGN }>>, 851 /// 标记该内核栈是否可以被释放 852 can_be_freed: bool, 853 } 854 855 impl KernelStack { 856 pub const SIZE: usize = 0x4000; 857 pub const ALIGN: usize = 0x4000; 858 859 pub fn new() -> Result<Self, SystemError> { 860 return Ok(Self { 861 stack: Some( 862 AlignedBox::<[u8; KernelStack::SIZE], { KernelStack::ALIGN }>::new_zeroed()?, 863 ), 864 can_be_freed: true, 865 }); 866 } 867 868 /// 根据已有的空间,构造一个内核栈结构体 869 /// 870 /// 仅仅用于BSP启动时,为idle进程构造内核栈。其他时候使用这个函数,很可能造成错误! 871 pub unsafe fn from_existed(base: VirtAddr) -> Result<Self, SystemError> { 872 if base.is_null() || base.check_aligned(Self::ALIGN) == false { 873 return Err(SystemError::EFAULT); 874 } 875 876 return Ok(Self { 877 stack: Some( 878 AlignedBox::<[u8; KernelStack::SIZE], { KernelStack::ALIGN }>::new_unchecked( 879 base.data() as *mut [u8; KernelStack::SIZE], 880 ), 881 ), 882 can_be_freed: false, 883 }); 884 } 885 886 /// 返回内核栈的起始虚拟地址(低地址) 887 pub fn start_address(&self) -> VirtAddr { 888 return VirtAddr::new(self.stack.as_ref().unwrap().as_ptr() as usize); 889 } 890 891 /// 返回内核栈的结束虚拟地址(高地址)(不包含该地址) 892 pub fn stack_max_address(&self) -> VirtAddr { 893 return VirtAddr::new(self.stack.as_ref().unwrap().as_ptr() as usize + Self::SIZE); 894 } 895 896 pub unsafe fn set_pcb(&mut self, pcb: Arc<ProcessControlBlock>) -> Result<(), SystemError> { 897 // 将一个Arc<ProcessControlBlock>放到内核栈的最低地址处 898 let p: *const ProcessControlBlock = Arc::into_raw(pcb); 899 let stack_bottom_ptr = self.start_address().data() as *mut *const ProcessControlBlock; 900 901 // 如果内核栈的最低地址处已经有了一个pcb,那么,这里就不再设置,直接返回错误 902 if unlikely(unsafe { !(*stack_bottom_ptr).is_null() }) { 903 return Err(SystemError::EPERM); 904 } 905 // 将pcb的地址放到内核栈的最低地址处 906 unsafe { 907 *stack_bottom_ptr = p; 908 } 909 910 return Ok(()); 911 } 912 913 /// 返回指向当前内核栈pcb的Arc指针 914 #[allow(dead_code)] 915 pub unsafe fn pcb(&self) -> Option<Arc<ProcessControlBlock>> { 916 // 从内核栈的最低地址处取出pcb的地址 917 let p = self.stack.as_ref().unwrap().as_ptr() as *const ProcessControlBlock; 918 if unlikely(p.is_null()) { 919 return None; 920 } 921 922 // 为了防止内核栈的pcb指针被释放,这里需要将其包装一下,使得Arc的drop不会被调用 923 let arc_wrapper: ManuallyDrop<Arc<ProcessControlBlock>> = 924 ManuallyDrop::new(Arc::from_raw(p)); 925 926 let new_arc: Arc<ProcessControlBlock> = Arc::clone(&arc_wrapper); 927 return Some(new_arc); 928 } 929 } 930 931 impl Drop for KernelStack { 932 fn drop(&mut self) { 933 if !self.stack.is_none() { 934 let pcb_ptr: Arc<ProcessControlBlock> = unsafe { 935 Arc::from_raw(self.stack.as_ref().unwrap().as_ptr() as *const ProcessControlBlock) 936 }; 937 drop(pcb_ptr); 938 } 939 // 如果该内核栈不可以被释放,那么,这里就forget,不调用AlignedBox的drop函数 940 if !self.can_be_freed { 941 let bx = self.stack.take(); 942 core::mem::forget(bx); 943 } 944 } 945 } 946 947 pub fn process_init() { 948 ProcessManager::init(); 949 } 950