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