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