strat9_kernel/ostd/
task.rs1#![allow(unsafe_code)]
11
12extern crate alloc;
13
14use alloc::sync::Arc;
15use core::sync::atomic::{AtomicU32, AtomicUsize, Ordering};
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19#[repr(transparent)]
20pub struct TaskId(u32);
21
22impl TaskId {
23 pub const fn new(id: u32) -> Self {
25 Self(id)
26 }
27
28 pub const fn as_u32(&self) -> u32 {
30 self.0
31 }
32
33 pub const fn as_usize(&self) -> usize {
35 self.0 as usize
36 }
37}
38
39impl From<u32> for TaskId {
40 fn from(id: u32) -> Self {
42 Self::new(id)
43 }
44}
45
46impl From<TaskId> for u32 {
47 fn from(id: TaskId) -> u32 {
49 id.0
50 }
51}
52
53impl core::fmt::Display for TaskId {
54 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
56 write!(f, "Task #{}", self.0)
57 }
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub enum TaskState {
63 Runnable,
65 Blocked,
67 Sleeping,
69 Stopped,
71 Exiting,
73 Idle,
75}
76
77pub struct TaskRef {
82 task_ptr: *mut TaskInner,
84 ref_count: Arc<AtomicUsize>,
86}
87
88unsafe impl Send for TaskRef {}
90unsafe impl Sync for TaskRef {}
92
93impl TaskRef {
94 pub unsafe fn new(task_ptr: *mut TaskInner) -> Self {
101 Self {
102 task_ptr,
103 ref_count: Arc::new(AtomicUsize::new(1)),
104 }
105 }
106
107 pub unsafe fn as_ref(&self) -> &TaskInner {
113 &*self.task_ptr
114 }
115
116 pub unsafe fn as_mut(&mut self) -> &mut TaskInner {
122 &mut *self.task_ptr
123 }
124
125 pub fn clone(&self) -> Self {
127 self.ref_count.fetch_add(1, Ordering::Relaxed);
128 Self {
129 task_ptr: self.task_ptr,
130 ref_count: Arc::clone(&self.ref_count),
131 }
132 }
133
134 pub fn ref_count(&self) -> usize {
136 self.ref_count.load(Ordering::Relaxed)
137 }
138
139 pub fn is_last_ref(&self) -> bool {
141 self.ref_count.load(Ordering::Relaxed) == 1
142 }
143}
144
145impl Drop for TaskRef {
146 fn drop(&mut self) {
148 if self.ref_count.fetch_sub(1, Ordering::Release) == 1 {
149 unsafe {
152 (*self.task_ptr).on_last_ref();
153 }
154 }
155 }
156}
157
158impl Clone for TaskRef {
159 fn clone(&self) -> Self {
161 self.clone()
162 }
163}
164
165pub struct TaskInner {
169 id: TaskId,
171 name: spin::Mutex<Option<alloc::string::String>>,
173 state: AtomicU32,
175 cpu_affinity: AtomicUsize,
177 priority: AtomicU32,
179}
180
181impl TaskInner {
182 pub fn new(id: TaskId) -> Self {
184 Self {
185 id,
186 name: spin::Mutex::new(None),
187 state: AtomicU32::new(TaskState::Runnable as u32),
188 cpu_affinity: AtomicUsize::new(usize::MAX), priority: AtomicU32::new(0),
190 }
191 }
192
193 pub fn id(&self) -> TaskId {
195 self.id
196 }
197
198 pub fn name(&self) -> Option<alloc::string::String> {
200 self.name.lock().clone()
201 }
202
203 pub fn set_name(&self, name: alloc::string::String) {
205 *self.name.lock() = Some(name);
206 }
207
208 pub fn state(&self) -> TaskState {
210 match self.state.load(Ordering::Relaxed) {
211 0 => TaskState::Runnable,
212 1 => TaskState::Blocked,
213 2 => TaskState::Sleeping,
214 3 => TaskState::Stopped,
215 4 => TaskState::Exiting,
216 5 => TaskState::Idle,
217 _ => TaskState::Runnable,
218 }
219 }
220
221 pub fn set_state(&self, state: TaskState) {
223 self.state.store(state as u32, Ordering::Relaxed);
224 }
225
226 pub fn cpu_affinity(&self) -> usize {
228 self.cpu_affinity.load(Ordering::Relaxed)
229 }
230
231 pub fn set_cpu_affinity(&self, mask: usize) {
233 self.cpu_affinity.store(mask, Ordering::Relaxed);
234 }
235
236 pub fn priority(&self) -> u32 {
238 self.priority.load(Ordering::Relaxed)
239 }
240
241 pub fn set_priority(&self, priority: u32) {
243 self.priority.store(priority, Ordering::Relaxed);
244 }
245
246 pub fn on_last_ref(&self) {
250 }
253}
254
255pub fn current_task() -> Option<TaskRef> {
259 None
262}
263
264pub struct TaskOptions {
266 name: Option<alloc::string::String>,
267 cpu_affinity: Option<usize>,
268 priority: Option<u32>,
269}
270
271impl TaskOptions {
272 pub fn new() -> Self {
274 Self {
275 name: None,
276 cpu_affinity: None,
277 priority: None,
278 }
279 }
280
281 pub fn name(mut self, name: alloc::string::String) -> Self {
283 self.name = Some(name);
284 self
285 }
286
287 pub fn cpu_affinity(mut self, affinity: usize) -> Self {
289 self.cpu_affinity = Some(affinity);
290 self
291 }
292
293 pub fn priority(mut self, priority: u32) -> Self {
295 self.priority = Some(priority);
296 self
297 }
298}
299
300impl Default for TaskOptions {
301 fn default() -> Self {
303 Self::new()
304 }
305}