safa_abi/raw/
processes.rs

1use core::ops::BitOr;
2
3use super::{Optional, RawSlice, RawSliceMut};
4
5#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
6#[repr(C)]
7/// ABI structures are structures that are passed to tasks by the parent task
8/// for now only stdio file descriptors are passed
9/// you get a pointer to them in the `r8` register at _start (the 5th argument)
10pub struct AbiStructures {
11    pub stdio: TaskStdio,
12}
13
14#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
15#[repr(C)]
16pub struct TaskStdio {
17    pub stdout: Optional<usize>,
18    pub stdin: Optional<usize>,
19    pub stderr: Optional<usize>,
20}
21
22impl TaskStdio {
23    pub fn new(stdout: Option<usize>, stdin: Option<usize>, stderr: Option<usize>) -> Self {
24        Self {
25            stdout: stdout.into(),
26            stdin: stdin.into(),
27            stderr: stderr.into(),
28        }
29    }
30}
31
32#[derive(Debug, Clone, Copy)]
33#[repr(C)]
34/// Flags for the [crate::syscalls::SyscallTable::SysPSpawn] syscall
35pub struct SpawnFlags(u8);
36impl SpawnFlags {
37    pub const CLONE_RESOURCES: Self = Self(1 << 0);
38    pub const CLONE_CWD: Self = Self(1 << 1);
39    pub const EMPTY: Self = Self(0);
40}
41
42impl BitOr for SpawnFlags {
43    type Output = Self;
44    fn bitor(self, rhs: Self) -> Self::Output {
45        Self(self.0 | rhs.0)
46    }
47}
48
49#[repr(u8)]
50#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub enum ContextPriority {
52    Low,
53    Medium,
54    High,
55}
56
57impl ContextPriority {
58    /// Returns the number of timeslices a thread with this priority should be given.
59    pub const fn timeslices(&self) -> u32 {
60        match self {
61            Self::Low => 1,
62            Self::Medium => 3,
63            Self::High => 5,
64        }
65    }
66}
67
68/// configuration for the spawn syscall
69#[repr(C)]
70pub struct PSpawnConfig {
71    /// config version for compatibility
72    /// added in kernel version 0.2.1 and therefore breaking compatibility with any program compiled for version below 0.2.1
73    /// revision 1: added env
74    /// revision 2: added priority (v0.4.0)
75    pub revision: u8,
76    pub name: RawSlice<u8>,
77    pub argv: RawSliceMut<RawSlice<u8>>,
78    pub flags: SpawnFlags,
79    pub stdio: *const TaskStdio,
80    pub env: RawSliceMut<RawSlice<u8>>,
81    pub priority: Optional<ContextPriority>,
82}
83
84impl PSpawnConfig {
85    pub fn new(
86        name: &str,
87        argv: *mut [&[u8]],
88        env: *mut [&[u8]],
89        flags: SpawnFlags,
90        stdio: &TaskStdio,
91        priority: Option<ContextPriority>,
92    ) -> Self {
93        let name = unsafe { RawSlice::from_slice(name.as_bytes()) };
94        let argv = unsafe { RawSliceMut::from_slices(argv) };
95        let env = unsafe { RawSliceMut::from_slices(env) };
96
97        Self {
98            revision: 2,
99            name,
100            argv,
101            env,
102            flags,
103            stdio: stdio as *const TaskStdio,
104            priority: priority.into(),
105        }
106    }
107}
108
109/// configuration for the thread spawn syscall
110/// for now it takes only a single argument pointer which is a pointer to an optional argument, that pointer is going to be passed to the thread as the second argument
111#[repr(C)]
112pub struct TSpawnConfig {
113    pub revision: u32,
114    pub argument_ptr: *const (),
115    pub priority: Optional<ContextPriority>,
116    /// The index of the CPU to append to, if it is None the kernel will choose one, use `0` for the boot CPU
117    pub cpu: Optional<usize>,
118}
119
120impl TSpawnConfig {
121    pub fn into_rust(&self) -> (*const (), Option<ContextPriority>, Option<usize>) {
122        (self.argument_ptr, self.priority.into(), self.cpu.into())
123    }
124
125    /// Create a new thread spawn configuration with the latest revision
126    pub fn new(
127        argument_ptr: *const (),
128        priority: Option<ContextPriority>,
129        cpu: Option<usize>,
130    ) -> Self {
131        Self {
132            revision: 0,
133            argument_ptr,
134            priority: priority.into(),
135            cpu: cpu.into(),
136        }
137    }
138}