good_os_framework/task/
thread.rs1use alloc::sync::Arc;
2use alloc::sync::Weak;
3use core::fmt::Debug;
4use core::sync::atomic::{AtomicU64, Ordering};
5use spin::RwLock;
6
7use super::context::Context;
8use super::process::WeakSharedProcess;
9use super::process::KERNEL_PROCESS;
10use super::scheduler::SCHEDULER;
11use super::stack::{KernelStack, UserStack};
12use crate::arch::gdt::Selectors;
13use crate::drivers::fpu::FpState;
14use crate::memory::KERNEL_PAGE_TABLE;
15
16pub(super) type SharedThread = Arc<RwLock<Thread>>;
17pub(super) type WeakSharedThread = Weak<RwLock<Thread>>;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
20pub struct ThreadId(pub u64);
21
22impl ThreadId {
23 fn new() -> Self {
24 static NEXT_ID: AtomicU64 = AtomicU64::new(0);
25 ThreadId(NEXT_ID.fetch_add(1, Ordering::Relaxed))
26 }
27}
28
29#[derive(Debug, Copy, Clone, PartialEq, Eq)]
30pub enum ThreadState {
31 Running,
32 Ready,
33 Blocked,
34 Waiting,
35 Terminated,
36}
37
38impl ThreadState {
39 pub fn is_active(&self) -> bool {
40 match self {
41 ThreadState::Running | ThreadState::Ready => true,
42 _ => false,
43 }
44 }
45}
46
47#[allow(dead_code)]
48pub struct Thread {
49 pub id: ThreadId,
50 pub state: ThreadState,
51 pub kernel_stack: KernelStack,
52 pub context: Context,
53 pub process: WeakSharedProcess,
54 pub fpu_context: FpState,
55}
56
57impl Thread {
58 pub fn new(process: WeakSharedProcess) -> Self {
61 let thread = Thread {
62 id: ThreadId::new(),
63 state: ThreadState::Ready,
64 context: Context::default(),
65 kernel_stack: KernelStack::new(),
66 process,
67 fpu_context: FpState::default(),
68 };
69
70 thread
71 }
72
73 pub fn get_init_thread() -> WeakSharedThread {
75 let thread = Self::new(Arc::downgrade(&KERNEL_PROCESS));
76 let thread = Arc::new(RwLock::new(thread));
77 KERNEL_PROCESS.write().threads.push_back(thread.clone());
78 Arc::downgrade(&thread)
80 }
81
82
83 pub fn new_kernel_thread(function: fn()) {
85 let mut thread = Self::new(Arc::downgrade(&KERNEL_PROCESS));
86
87 thread.context.init(
88 function as usize,
89 thread.kernel_stack.end_address(),
90 KERNEL_PAGE_TABLE.lock().physical_address,
91 Selectors::get_kernel_segments(),
92 );
93
94
95
96 let thread = Arc::new(RwLock::new(thread));
97
98
99 SCHEDULER.lock().add(Arc::downgrade(&thread));
100 KERNEL_PROCESS.write().threads.push_back(thread);
101
102 }
103
104 pub fn new_user_thread(process: WeakSharedProcess, entry_point: usize) {
106 let mut thread = Self::new(process.clone());
107 let process = process.upgrade().unwrap();
109 let mut process = process.write();
110 let user_stack = UserStack::new(&mut process.page_table);
111
112 thread.context.init(
113 entry_point,
114 user_stack.end_address,
115 process.page_table.physical_address,
116 Selectors::get_user_segments(),
117 );
118
119 let thread = Arc::new(RwLock::new(thread));
120 SCHEDULER.lock().add(Arc::downgrade(&thread));
121 process.threads.push_back(thread.clone());
122 }
123}
124
125