kernel_api/threading/
state.rs1use core::fmt::{Debug, Formatter};
2use core::ptr::addr_of;
3use core::sync::atomic::{Ordering, AtomicU128};
4
5fn into_raw(state: ThreadState) -> u128 {
6 let tag = unsafe { *addr_of!(state).cast::<u8>() } as u128;
7
8 match state {
9 ThreadState::Killed(exit_code) => {
10 let upper = exit_code as u128;
11 (upper << 64) | tag
12 }
13 _ => tag,
14 }
15}
16
17fn from_raw(raw: u128) -> ThreadState {
18 let tag = raw as u8;
19
20 match tag {
21 0 => ThreadState::Ready,
22 1 => ThreadState::Running,
23 2 => ThreadState::Parked,
24 3 => ThreadState::NearlyParked,
25 4 => ThreadState::Killed((raw >> 64) as isize),
26 _ => unreachable!("invalid thread state"),
27 }
28}
29
30pub struct AtomicThreadState(AtomicU128);
31
32impl AtomicThreadState {
33 pub fn new(state: ThreadState) -> Self {
34 AtomicThreadState(AtomicU128::new(into_raw(state)))
35 }
36
37 pub fn store(&self, state: ThreadState, ordering: Ordering) {
38 self.0.store(into_raw(state), ordering);
39 }
40
41 pub fn load(&self, ordering: Ordering) -> ThreadState{
42 from_raw(self.0.load(ordering))
43 }
44
45 pub fn compare_exchange(&self, current: ThreadState, new: ThreadState, success: Ordering, failure: Ordering) -> Result<ThreadState, ThreadState> {
46 let current = into_raw(current);
47 let new = into_raw(new);
48 self.0.compare_exchange(current, new, success, failure)
49 .map(from_raw)
50 .map_err(from_raw)
51 }
52
53 pub fn fetch_update(&self, set_order: Ordering, fetch_order: Ordering, mut f: impl FnMut(ThreadState) -> Option<ThreadState>) -> Result<ThreadState, ThreadState> {
54 self.0.fetch_update(set_order, fetch_order, |val| f(from_raw(val)).map(into_raw))
55 .map(from_raw)
56 .map_err(from_raw)
57 }
58
59 pub fn running(&self) -> bool {
60 matches!(
61 self.load(Ordering::SeqCst),
62 ThreadState::Running,
63 )
64 }
65
66 pub fn runnable(&self) -> bool {
67 matches!(
68 self.load(Ordering::SeqCst),
69 ThreadState::Running | ThreadState::Ready | ThreadState::NearlyParked,
70 )
71 }
72}
73
74impl Debug for AtomicThreadState {
75 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
76 write!(f, "AtomicThreadState {{ {:?} }}", self.load(Ordering::Relaxed))
77 }
78}
79
80#[derive(Debug)]
81#[repr(u8)]
82pub enum ThreadState {
83 Ready = 0,
85 Running = 1,
87 Parked = 2,
89 NearlyParked = 3,
91 Killed(isize) = 4,
92}