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