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