starnix_core/ptrace/
stop_state.rs1use std::sync::atomic::{AtomicU8, Ordering};
6
7pub struct AtomicStopState {
8 inner: AtomicU8,
9}
10
11impl AtomicStopState {
12 pub fn new(state: StopState) -> Self {
13 Self { inner: AtomicU8::new(state as u8) }
14 }
15
16 pub fn load(&self, ordering: Ordering) -> StopState {
17 let v = self.inner.load(ordering);
18 unsafe { std::mem::transmute(v) }
21 }
22
23 pub fn store(&self, state: StopState, ordering: Ordering) {
24 self.inner.store(state as u8, ordering)
25 }
26}
27
28#[derive(Clone, Copy, Debug, PartialEq)]
31#[repr(u8)]
32pub enum StopState {
33 Waking,
36 Awake,
38 ForceWaking,
41 ForceAwake,
42
43 GroupStopping,
45 GroupStopped,
47 SignalDeliveryStopping,
50 SignalDeliveryStopped,
52 PtraceEventStopping,
58 PtraceEventStopped,
60 SyscallEnterStopping,
62 SyscallEnterStopped,
63 SyscallExitStopping,
65 SyscallExitStopped,
66}
67
68impl StopState {
69 pub fn is_stopping_or_stopped(&self) -> bool {
71 self.is_stopped() || self.is_stopping()
72 }
73
74 pub fn is_stopping(&self) -> bool {
76 match *self {
77 StopState::GroupStopping
78 | StopState::SignalDeliveryStopping
79 | StopState::PtraceEventStopping
80 | StopState::SyscallEnterStopping
81 | StopState::SyscallExitStopping => true,
82 _ => false,
83 }
84 }
85
86 pub fn is_stopped(&self) -> bool {
88 match *self {
89 StopState::GroupStopped
90 | StopState::SignalDeliveryStopped
91 | StopState::PtraceEventStopped
92 | StopState::SyscallEnterStopped
93 | StopState::SyscallExitStopped => true,
94 _ => false,
95 }
96 }
97
98 pub fn finalize(&self) -> Result<StopState, ()> {
100 match *self {
101 StopState::GroupStopping => Ok(StopState::GroupStopped),
102 StopState::SignalDeliveryStopping => Ok(StopState::SignalDeliveryStopped),
103 StopState::PtraceEventStopping => Ok(StopState::PtraceEventStopped),
104 StopState::Waking => Ok(StopState::Awake),
105 StopState::ForceWaking => Ok(StopState::ForceAwake),
106 StopState::SyscallEnterStopping => Ok(StopState::SyscallEnterStopped),
107 StopState::SyscallExitStopping => Ok(StopState::SyscallExitStopped),
108 _ => Err(()),
109 }
110 }
111
112 pub fn is_downgrade(&self, new_state: &StopState) -> bool {
113 match *self {
114 StopState::GroupStopped => *new_state == StopState::GroupStopping,
115 StopState::SignalDeliveryStopped => *new_state == StopState::SignalDeliveryStopping,
116 StopState::PtraceEventStopped => *new_state == StopState::PtraceEventStopping,
117 StopState::SyscallEnterStopped => *new_state == StopState::SyscallEnterStopping,
118 StopState::SyscallExitStopped => *new_state == StopState::SyscallExitStopping,
119 StopState::Awake => *new_state == StopState::Waking,
120 _ => false,
121 }
122 }
123
124 pub fn is_waking_or_awake(&self) -> bool {
125 *self == StopState::Waking
126 || *self == StopState::Awake
127 || *self == StopState::ForceWaking
128 || *self == StopState::ForceAwake
129 }
130
131 pub fn is_in_progress(&self) -> bool {
134 *self == StopState::Waking
135 || *self == StopState::ForceWaking
136 || *self == StopState::GroupStopping
137 || *self == StopState::SignalDeliveryStopping
138 || *self == StopState::PtraceEventStopping
139 || *self == StopState::SyscallEnterStopping
140 || *self == StopState::SyscallExitStopping
141 }
142
143 pub fn ptrace_only(&self) -> bool {
144 !self.is_waking_or_awake()
145 && *self != StopState::GroupStopped
146 && *self != StopState::GroupStopping
147 }
148
149 pub fn is_illegal_transition(&self, new_state: StopState) -> bool {
150 *self == StopState::ForceAwake
151 || (*self == StopState::ForceWaking && new_state != StopState::ForceAwake)
152 || new_state == *self
153 || (self.is_downgrade(&new_state) && *self != StopState::Awake)
157 }
158
159 pub fn is_force(&self) -> bool {
160 *self == StopState::ForceAwake || *self == StopState::ForceWaking
161 }
162
163 pub fn as_in_progress(&self) -> Result<StopState, ()> {
164 match *self {
165 StopState::GroupStopped => Ok(StopState::GroupStopping),
166 StopState::SignalDeliveryStopped => Ok(StopState::SignalDeliveryStopping),
167 StopState::PtraceEventStopped => Ok(StopState::PtraceEventStopping),
168 StopState::Awake => Ok(StopState::Waking),
169 StopState::ForceAwake => Ok(StopState::ForceWaking),
170 StopState::SyscallEnterStopped => Ok(StopState::SyscallEnterStopping),
171 StopState::SyscallExitStopped => Ok(StopState::SyscallExitStopping),
172 _ => Ok(*self),
173 }
174 }
175}