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