1pub mod basic {
3 use crate::apex::time::basic::*;
4 use crate::apex::types::basic::*;
5
6 pub type ProcessName = ApexName;
8 pub type ProcessIndex = ApexInteger;
10 pub type StackSize = ApexUnsigned;
12
13 pub type Priority = ApexInteger;
15 pub const MIN_PRIORITY_VALUE: Priority = 1;
16 pub const MAX_PRIORITY_VALUE: Priority = 239;
17
18 pub type LockLevel = ApexInteger;
20 pub const MIN_LOCK_LEVEL: LockLevel = 0;
21 pub const MAX_LOCK_LEVEL: LockLevel = 16;
22
23 pub type SystemAddress = extern "C" fn();
25
26 pub type ProcessId = ApexLongInteger;
32 pub const NULL_PROCESS_ID: ProcessId = 0;
33 pub const MAIN_PROCESS_ID: ProcessId = -1;
34
35 #[repr(u32)]
37 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
38 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39 #[cfg_attr(feature = "strum", derive(strum::FromRepr))]
40 pub enum ProcessState {
41 Dormant = 0,
42 Ready = 1,
43 Running = 2,
44 Waiting = 3,
45 Faulted = 4,
46 }
47
48 #[repr(u32)]
50 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
51 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52 #[cfg_attr(feature = "strum", derive(strum::FromRepr))]
53 pub enum Deadline {
54 Soft = 0,
55 Hard = 1,
56 }
57
58 #[repr(C)]
60 #[derive(Debug, Clone, PartialEq, Eq)]
61 pub struct ApexProcessAttribute {
62 pub period: ApexSystemTime,
63 pub time_capacity: ApexSystemTime,
64 pub entry_point: SystemAddress,
65 pub stack_size: StackSize,
66 pub base_priority: Priority,
67 pub deadline: Deadline,
68 pub name: ProcessName,
69 }
70
71 #[repr(C)]
73 #[derive(Debug, Clone, PartialEq, Eq)]
74 pub struct ApexProcessStatus {
75 pub deadline_time: ApexSystemTime,
76 pub current_priority: Priority,
77 pub process_state: ProcessState,
78 pub attributes: ApexProcessAttribute,
79 }
80
81 pub trait ApexProcessP4 {
83 fn create_process(attributes: &ApexProcessAttribute) -> Result<ProcessId, ErrorReturnCode>;
97
98 fn start(process_id: ProcessId) -> Result<(), ErrorReturnCode>;
99 }
100
101 pub trait ApexProcessP1: ApexProcessP4 {
102 fn set_priority(process_id: ProcessId, priority: Priority) -> Result<(), ErrorReturnCode>;
103
104 fn suspend_self(time_out: ApexSystemTime) -> Result<(), ErrorReturnCode>;
105
106 fn suspend(process_id: ProcessId) -> Result<(), ErrorReturnCode>;
107
108 fn resume(process_id: ProcessId) -> Result<(), ErrorReturnCode>;
109
110 fn stop_self();
111
112 fn stop(process_id: ProcessId) -> Result<(), ErrorReturnCode>;
113
114 fn delayed_start(
115 process_id: ProcessId,
116 delay_time: ApexSystemTime,
117 ) -> Result<(), ErrorReturnCode>;
118
119 fn lock_preemption() -> Result<LockLevel, ErrorReturnCode>;
120
121 fn unlock_preemption() -> Result<LockLevel, ErrorReturnCode>;
122
123 fn get_my_id() -> Result<ProcessId, ErrorReturnCode>;
124
125 fn get_process_id(process_name: ProcessName) -> Result<ProcessId, ErrorReturnCode>;
126
127 fn get_process_status(process_id: ProcessId) -> Result<ApexProcessStatus, ErrorReturnCode>;
128
129 fn initialize_process_core_affinity(
131 process_id: ProcessId,
132 processor_core_id: ProcessorCoreId,
133 ) -> Result<(), ErrorReturnCode>;
134
135 fn get_my_processor_core_id() -> ProcessorCoreId;
136
137 fn get_my_index() -> Result<ProcessIndex, ErrorReturnCode>;
138 }
139}
140
141pub mod abstraction {
143 use core::marker::PhantomData;
144 use core::sync::atomic::AtomicPtr;
145
146 use super::basic::{ApexProcessAttribute, ApexProcessP1, ApexProcessP4, ApexProcessStatus};
147 pub use super::basic::{
149 Deadline, LockLevel, Priority, ProcessId, ProcessIndex, ProcessName, StackSize,
150 SystemAddress, MAIN_PROCESS_ID, MAX_LOCK_LEVEL, MAX_PRIORITY_VALUE, MIN_LOCK_LEVEL,
151 MIN_PRIORITY_VALUE, NULL_PROCESS_ID,
152 };
153 use crate::prelude::*;
154
155 #[derive(Debug, Clone, PartialEq, Eq)]
156 pub struct ProcessAttribute {
157 pub period: SystemTime,
158 pub time_capacity: SystemTime,
159 pub entry_point: SystemAddress,
160 pub stack_size: StackSize,
161 pub base_priority: Priority,
162 pub deadline: Deadline,
163 pub name: Name,
164 }
165
166 impl From<ProcessAttribute> for ApexProcessAttribute {
167 fn from(p: ProcessAttribute) -> Self {
168 ApexProcessAttribute {
169 period: p.period.into(),
170 time_capacity: p.time_capacity.into(),
171 entry_point: p.entry_point,
172 stack_size: p.stack_size,
173 base_priority: p.base_priority,
174 deadline: p.deadline,
175 name: p.name.into(),
176 }
177 }
178 }
179
180 impl From<ApexProcessAttribute> for ProcessAttribute {
181 fn from(p: ApexProcessAttribute) -> Self {
182 ProcessAttribute {
183 period: p.period.into(),
184 time_capacity: p.time_capacity.into(),
185 entry_point: p.entry_point,
186 stack_size: p.stack_size,
187 base_priority: p.base_priority,
188 deadline: p.deadline,
189 name: Name::new(p.name),
190 }
191 }
192 }
193
194 #[derive(Debug, Clone, PartialEq, Eq)]
195 pub struct ProcessStatus {
196 pub deadline_time: SystemTime,
197 pub current_priority: Priority,
198 pub process_state: super::basic::ProcessState,
199 pub attributes: ProcessAttribute,
200 }
201
202 impl From<ApexProcessStatus> for ProcessStatus {
203 fn from(p: ApexProcessStatus) -> Self {
204 ProcessStatus {
205 deadline_time: p.deadline_time.into(),
206 current_priority: p.current_priority,
207 process_state: p.process_state,
208 attributes: p.attributes.into(),
209 }
210 }
211 }
212
213 #[derive(Debug)]
214 pub struct Process<P: ApexProcessP4> {
215 _p: PhantomData<AtomicPtr<P>>,
216 id: ProcessId,
217 }
218
219 impl<P: ApexProcessP4> Clone for Process<P> {
220 fn clone(&self) -> Self {
221 Self {
222 _p: self._p,
223 id: self.id,
224 }
225 }
226 }
227
228 pub trait ApexProcessP1Ext: ApexProcessP1 + Sized {
229 fn get_process(name: Name) -> Result<Process<Self>, Error>;
230 }
231
232 impl<P: ApexProcessP1> ApexProcessP1Ext for P {
233 fn get_process(name: Name) -> Result<Process<P>, Error> {
234 let id = P::get_process_id(name.into())?;
235 Ok(Process {
236 _p: Default::default(),
237 id,
238 })
239 }
240 }
241
242 impl<P: ApexProcessP4> Process<P> {
243 pub fn start(&self) -> Result<(), Error> {
244 P::start(self.id)?;
245 Ok(())
246 }
247
248 pub fn id(&self) -> ProcessId {
249 self.id
250 }
251 }
252
253 impl<P: ApexProcessP1> Process<P> {
254 pub fn from_name(name: Name) -> Result<Process<P>, Error> {
255 P::get_process(name)
256 }
257
258 pub fn get_self() -> Result<Process<P>, Error> {
259 let id = P::get_my_id()?;
260 Ok(Process {
261 _p: Default::default(),
262 id,
263 })
264 }
265
266 pub fn set_priority(&self, priority: Priority) -> Result<(), Error> {
267 P::set_priority(self.id, priority)?;
268 Ok(())
269 }
270
271 pub fn suspend_self(time_out: SystemTime) -> Result<(), Error> {
272 P::suspend_self(time_out.into())?;
273 Ok(())
274 }
275
276 pub fn suspend(&self) -> Result<(), Error> {
277 P::suspend(self.id)?;
278 Ok(())
279 }
280
281 pub fn resume(&self) -> Result<(), Error> {
282 P::resume(self.id)?;
283 Ok(())
284 }
285
286 pub fn stop_self() {
287 P::stop_self()
288 }
289
290 pub fn stop(&self) -> Result<(), Error> {
291 P::stop(self.id)?;
292 Ok(())
293 }
294
295 pub fn delayed_start(&self, delay_time: SystemTime) -> Result<(), Error> {
296 P::delayed_start(self.id, delay_time.into())?;
297 Ok(())
298 }
299
300 pub fn lock_preemption() -> Result<LockLevel, Error> {
301 Ok(P::lock_preemption()?)
302 }
303
304 pub fn unlock_preemption() -> Result<LockLevel, Error> {
305 Ok(P::unlock_preemption()?)
306 }
307
308 pub fn status(&self) -> ProcessStatus {
309 P::get_process_status(self.id).unwrap().into()
314 }
315
316 pub fn get_my_processor_core_id() -> ProcessorCoreId {
317 P::get_my_processor_core_id()
318 }
319
320 pub fn get_my_index() -> Result<ProcessIndex, Error> {
321 Ok(P::get_my_index()?)
322 }
323 }
324
325 impl<P: ApexProcessP4> StartContext<P> {
326 pub fn create_process(&mut self, attr: ProcessAttribute) -> Result<Process<P>, Error> {
327 let id = P::create_process(&attr.into())?;
328 Ok(Process {
329 _p: Default::default(),
330 id,
331 })
332 }
333 }
334
335 impl<P: ApexProcessP1> StartContext<P> {
336 pub fn initialize_process_core_affinity(
337 &self,
338 process: &Process<P>,
339 processor_core_id: ProcessorCoreId,
340 ) -> Result<(), Error> {
341 P::initialize_process_core_affinity(process.id, processor_core_id)?;
342 Ok(())
343 }
344 }
345}