PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
proc.h
Go to the documentation of this file.
1#ifndef _SYS_PROC_H
2#define _SYS_PROC_H 1
3
4#include <stdatomic.h>
5#include <stdint.h>
6#include <stdio.h>
7
8#if defined(__cplusplus)
9extern "C"
10{
11#endif
12
13#include "_libstd/ERR.h"
14#include "_libstd/NULL.h"
15#include "_libstd/PAGE_SIZE.h"
16#include "_libstd/clock_t.h"
17#include "_libstd/config.h"
18#include "_libstd/fd_t.h"
19
20#include "_libstd/pid_t.h"
21#include "_libstd/tid_t.h"
22
23/**
24 * @brief Process management header.
25 * @ingroup libstd
26 * @defgroup libstd_sys_proc Process management
27 *
28 * The `sys/proc.h` header handles process management, including process spawning, managing a processes address space,
29 * scheduling, and similar.
30 *
31 * @{
32 */
33
34/**
35 * @brief Priority type.
36 * @typedef priority_t
37 *
38 * The `priority_t` type is used to store the scheduling priority of a process.
39 *
40 */
42
43#define PRIORITY_MAX 63 ///< The maximum priority value, inclusive.
44#define PRIORITY_MAX_USER 31 ///< The maximum priority user space is allowed to specify, inclusive.
45#define PRIORITY_MIN 0 ///< The minimum priority value.
46
47/**
48 * @brief Spawn behaviour flags.
49 * @enum spawn_flags_t
50 */
51typedef enum
52{
53 SPAWN_DEFAULT = 0, ///< Default spawn behaviour.
54 /**
55 * Starts the spawned process in a suspended state. The process will not begin executing until a "start" note is
56 * received.
57 *
58 * The purpose of this flag is to allow the parent process to modify the child process before it starts executing,
59 * for example modifying its environment variables.
60 */
61 SPAWN_SUSPEND = 1 << 0,
62 SPAWN_EMPTY_FDS = 1 << 1, ///< Dont inherit the file descriptors of the parent process.
63 SPAWN_STDIO_FDS = 1 << 2, ///< Only inherit stdin, stdout and stderr from the parent process.
64 SPAWN_EMPTY_ENV = 1 << 3, ///< Don't inherit the parent's environment variables.
65 SPAWN_EMPTY_CWD = 1 << 4, ///< Don't inherit the parent's current working directory, starts at root (/).
66 SPAWN_EMPTY_GROUP = 1 << 5, ///< Don't inherit the parent's process group, instead create a new group.
67 SPAWN_COPY_NS = 1 << 6, ///< Don't share the parent's namespace, instead create a new copy of it.
69 1 << 7, ///< Create a new empty namespace, the new namespace will not contain any mountpoints or even a root.
71 SPAWN_EMPTY_NS ///< Empty all inheritable resources.
73
74/**
75 * @brief System call for spawning new processes.
76 *
77 * By default, the spawned process will inherit the file table, environment variables, priority and current
78 * working directory of the parent process by creating a copy. Additionally the child will exist within the same
79 * namespace as the parent.
80 *
81 * @param argv A NULL-terminated array of strings, where `argv[0]` is the filepath to the desired executable.
82 * @param flags Spawn behaviour flags.
83 * @return On success, the childs pid. On failure, `ERR` and `errno` is set.
84 */
85pid_t spawn(const char** argv, spawn_flags_t flags);
86
87/**
88 * @brief System call to retrieve the current pid.
89 *
90 * @return The running processes pid.
91 */
92pid_t getpid(void);
93
94/**
95 * @brief System call to retrieve the current tid.
96 *
97 * @return The running threads tid.
98 */
99tid_t gettid(void);
100
101/**
102 * @brief Convert a size in bytes to pages.
103 *
104 * @param amount The amount of bytes.
105 * @return The amount of pages.
106 */
107#define BYTES_TO_PAGES(amount) (((amount) + PAGE_SIZE - 1) / PAGE_SIZE)
108
109/**
110 * @brief Size of an object in pages.
111 *
112 * @param object The object to calculate the page size of.
113 * @return The amount of pages.
114 */
115#define PAGE_SIZE_OF(object) BYTES_TO_PAGES(sizeof(object))
116
117/**
118 * @brief Memory protection flags.
119 * @typedef prot_t
120 */
121typedef enum
122{
123 PROT_NONE = 0, ///< Invalid memory, cannot be accessed.
124 PROT_READ = (1 << 0), ///< Readable memory.
125 PROT_WRITE = (1 << 1), ///< Writable memory.
126 PROT_EXECUTE = (1 << 2) ///< Executable memory.
128
129/**
130 * @brief System call to map memory from a file.
131 *
132 * The `mmap()` function maps memory to the currently running processes address space from a file, this is the only way
133 * to allocate virtual memory from userspace. An example usage would be to map the `/dev/const/zero` file which would
134 * allocate zeroed memory.
135 *
136 * @param fd The open file descriptor of the file to be mapped.
137 * @param address The desired virtual destination address, if equal to `NULL` the kernel will choose a available
138 * address, will be rounded down to the nearest page multiple.
139 * @param length The length of the segment to be mapped, note that this length will be rounded up to the nearest page
140 * multiple by the kernel factoring in page boundaries.
141 * @param prot Protection flags, must have at least `PROT_READ` set.
142 * @return On success, returns the address of the mapped memory, will always be page aligned, on failure returns `NULL`
143 * and errno is set.
144 */
145void* mmap(fd_t fd, void* address, size_t length, prot_t prot);
146
147/**
148 * @brief System call to unmap mapped memory.
149 *
150 * The `munmap()` function unmaps memory from the currently running processes address space.
151 *
152 * @param address The starting virtual address of the memory area to be unmapped.
153 * @param length The length of the memory area to be unmapped.
154 * @return On success, returns the address of the unmapped memory, on failure returns `NULL` and errno is set.
155 */
156void* munmap(void* address, size_t length);
157
158/**
159 * @brief System call to change the protection flags of memory.
160 *
161 * The `mprotect()` changes the protection flags of a virtual memory area in the currently running processes address
162 * space.
163 *
164 * @param address The starting virtual address of the memory area to be modified.
165 * @param length The length of the memory area to be modifed.
166 * @param prot The new protection flags of the memory area, if equal to `PROT_NONE` the memory area will be
167 * unmapped.
168 * @return On success, returns the address of the modified memory area, on failure returns `NULL` and errno is set.
169 */
170void* mprotect(void* address, size_t length, prot_t prot);
171
172/**
173 * @brief Futex operation enum.
174 *
175 * The `futex_op_t` enum is used to specify the desired futex operation in the `futex()` function.
176 *
177 */
178typedef enum
179{
180 /**
181 * @brief Wait until the timeout expires or the futex value changes.
182 *
183 * If the value at the futex address is not equal to `val`, the call returns immediately with `EAGAIN`.
184 * Otherwise, the calling thread is put to sleep until another thread wakes it up or the specified timeout expires.
185 */
187 /**
188 * @brief Wake up one or more threads waiting on the futex.
189 *
190 * Wakes up a maximum of `val` number of threads that are currently waiting on the futex at the specified address.
191 * If `val` is `FUTEX_ALL`, all waiting threads are woken up.
192 */
194} futex_op_t;
195
196/**
197 * @brief Futex wake all constant.
198 *
199 * The `FUTEX_ALL` constant can be used as the `val` argument when using the `FUTEX_WAIT` operating in the `futex()`
200 * function to wake upp all waiters.
201 *
202 */
203#define FUTEX_ALL UINT64_MAX
204
205/**
206 * @brief System call for fast user space mutual exclusion.
207 *
208 * The `futex()` function provides a fast user-space syncronization mechanism. It can be used to implement userspace
209 * mutexes, conditional variables, etc.
210 *
211 * @param addr A pointer to an atomic 64-bit unsigned integer.
212 * @param val The value used by the futex operation, its meaning depends on the operation.
213 * @param op The futex operation to perform (e.g., `FUTEX_WAIT` or `FUTEX_WAKE`).
214 * @param timeout An optional timeout for `FUTEX_WAIT`. If `CLOCKS_NEVER`, it waits forever.
215 * @return On success, depends on the operation. On failure, `ERR` and errno is set.
216 */
217uint64_t futex(atomic_uint64_t* addr, uint64_t val, futex_op_t op, clock_t timeout);
218
219/**
220 * @brief System call for retreving the time since boot.
221 *
222 * The `uptime()` function retrieves the system uptime since boot in clock ticks.
223 *
224 * @return The system uptime in clock ticks.
225 */
226clock_t uptime(void);
227
228/**
229 * @brief System call for sleeping.
230 *
231 * The `nanosleep()` function suspends the execution of the calling thread for a specified duration.
232 *
233 * @param timeout The duration in nanoseconds for which to sleep, if equal to `CLOCKS_NEVER` then it will sleep forever,
234 * not sure why you would want to do that but you can.
235 * @return On success, `0`. On failure, `ERR` and errno is set.
236 */
237uint64_t nanosleep(clock_t timeout);
238
239/**
240 * @brief Synchronization object.
241 *
242 * The `sync_t` structure is used to implement user space synchronization primitives. Its the object mapped when calling
243 * 'mmap()' on a opened sync file. For more information check the `sync.h` header.
244 *
245 * @see sync.h
246 */
247typedef struct
248{
249 atomic_uint64_t value; ///< The value of the sync object.
250} sync_t;
251
252/**
253 * @brief Note handler function type.
254 */
255typedef void (*note_func_t)(char* note);
256
257/**
258 * @brief System call that sets the handler to be called when a note is received.
259 *
260 * A note handler must either exit the thread or call `noted()`.
261 *
262 * If no handler is registered, the thread is killed when a note is received.
263 *
264 * @warning It is preferred to use `atnotify()` instead of this function as using this will prevent the standard library
265 * from handling notes.
266 *
267 * @see kernel_ipc_note
268 *
269 * @param handler The handler function to be called on notes, can be `NULL` to unregister the current handler.
270 * @return On success, `0`. On failure, `ERR` and errno is set.
271 */
273
274/**
275 * @brief System call that notifies the kernel that the current note has been handled.
276 *
277 * Should only be called from within a handler registered with `notify()` but NOT with `atnotify()`.
278 *
279 * If a note is not currently being handled, the thread is killed.
280 *
281 * @see kernel_ipc_note
282 *
283 * @return Never returns, instead resumes execution of the thread where it left off before the note was delivered.
284 */
285_NORETURN void noted(void);
286
287/**
288 * @brief Helper for comparing the first word of a string.
289 *
290 * @param string The string.
291 * @param word The word to compare against.
292 * @return On match, returns `0`. On mismatch, returns a non-zero value.
293 */
294int64_t wordcmp(const char* string, const char* word);
295
296/**
297 * @brief Action type for atnotify().
298 * @enum atnotify_t
299 */
300typedef enum
301{
305
306/**
307 * @brief User space `atnotify()` handler function type.
308 */
309typedef uint64_t (*atnotify_func_t)(char* note);
310
311/**
312 * @brief Adds or removes a handler to be called in user space when a note is received.
313 *
314 * If the return value of a handler is `ERR`, the process will exit.
315 *
316 * @param handler The handler function to be modified.
317 * @param action The action to perform.
318 * @return On success, `0`. On failure, `ERR` and errno is set.
319 */
321
322/**
323 * @brief System call that handles pending notes for the current thread.
324 *
325 * Should only be called from an interrupt context.
326 *
327 * If the frame is not from user space, this function will return immediately.
328 *
329 * @param frame The interrupt frame of the current interrupt.
330 * @return On success, `true` if a note was handled, `false` otherwise.
331 */
332_NORETURN void exits(const char* status);
333
334/**
335 * @brief Helper for sending the "kill" command to a process.
336 *
337 * @param pid The PID of the process to send the command to.
338 * @return On success, `0`. On failure, `ERR` and `errno` is set.
339 */
340uint64_t kill(pid_t pid);
341
342/**
343 * @brief Architecture specific thread data codes.
344 * @typedef arch_prctl_t
345 */
346typedef enum
347{
348 ARCH_GET_FS = 0, ///< Get the FS base address.
349 ARCH_SET_FS = 1, ///< Set the FS base address.
351
352/**
353 * @brief System call for setting architecture specific thread data.
354 *
355 * @param op The operation to perform.
356 * @param addr If getting data, a pointer to store the retrieved address. If setting data, the address to set.
357 * @return On success, `0`. On failure, `ERR` and `errno` is set.
358 */
360
361#if defined(__cplusplus)
362}
363#endif
364
365#endif
366
367/** @} */
#define _NORETURN
Definition config.h:28
static uintptr_t address
Mapped virtual address of the HPET registers.
Definition hpet.c:96
void * mprotect(void *address, size_t length, prot_t prot)
System call to change the protection flags of memory.
Definition mprotect.c:6
atnotify_t
Action type for atnotify().
Definition proc.h:301
void(* note_func_t)(char *note)
Note handler function type.
Definition proc.h:255
futex_op_t
Futex operation enum.
Definition proc.h:179
_NORETURN void exits(const char *status)
System call that handles pending notes for the current thread.
Definition proc_exit.c:7
arch_prctl_t
Architecture specific thread data codes.
Definition proc.h:347
void * mmap(fd_t fd, void *address, size_t length, prot_t prot)
System call to map memory from a file.
Definition mmap.c:6
uint64_t(* atnotify_func_t)(char *note)
User space atnotify() handler function type.
Definition proc.h:309
tid_t gettid(void)
System call to retrieve the current tid.
Definition gettid.c:6
uint64_t futex(atomic_uint64_t *addr, uint64_t val, futex_op_t op, clock_t timeout)
System call for fast user space mutual exclusion.
Definition futex.c:6
int64_t wordcmp(const char *string, const char *word)
Helper for comparing the first word of a string.
Definition wordcmp.c:5
spawn_flags_t
Spawn behaviour flags.
Definition proc.h:52
pid_t spawn(const char **argv, spawn_flags_t flags)
System call for spawning new processes.
Definition spawn.c:6
uint64_t kill(pid_t pid)
Helper for sending the "kill" command to a process.
Definition kill.c:4
uint64_t arch_prctl(arch_prctl_t op, uintptr_t addr)
System call for setting architecture specific thread data.
Definition arch_prctl.c:6
uint64_t atnotify(atnotify_func_t handler, atnotify_t action)
Adds or removes a handler to be called in user space when a note is received.
Definition atnotify.c:7
uint64_t notify(note_func_t handler)
System call that sets the handler to be called when a note is received.
Definition notify.c:5
clock_t uptime(void)
System call for retreving the time since boot.
Definition uptime.c:6
prot_t
Memory protection flags.
Definition proc.h:122
pid_t getpid(void)
System call to retrieve the current pid.
Definition getpid.c:6
uint8_t priority_t
Priority type.
Definition proc.h:41
uint64_t nanosleep(clock_t timeout)
System call for sleeping.
Definition nanosleep.c:6
void * munmap(void *address, size_t length)
System call to unmap mapped memory.
Definition munmap.c:6
_NORETURN void noted(void)
System call that notifies the kernel that the current note has been handled.
Definition noted.c:5
@ ATNOTIFY_REMOVE
Definition proc.h:303
@ ATNOTIFY_ADD
Definition proc.h:302
@ FUTEX_WAKE
Wake up one or more threads waiting on the futex.
Definition proc.h:193
@ FUTEX_WAIT
Wait until the timeout expires or the futex value changes.
Definition proc.h:186
@ ARCH_GET_FS
Get the FS base address.
Definition proc.h:348
@ ARCH_SET_FS
Set the FS base address.
Definition proc.h:349
@ SPAWN_EMPTY_GROUP
Don't inherit the parent's process group, instead create a new group.
Definition proc.h:66
@ SPAWN_EMPTY_FDS
Dont inherit the file descriptors of the parent process.
Definition proc.h:62
@ SPAWN_DEFAULT
Default spawn behaviour.
Definition proc.h:53
@ SPAWN_EMPTY_ALL
Empty all inheritable resources.
Definition proc.h:70
@ SPAWN_STDIO_FDS
Only inherit stdin, stdout and stderr from the parent process.
Definition proc.h:63
@ SPAWN_EMPTY_NS
Create a new empty namespace, the new namespace will not contain any mountpoints or even a root.
Definition proc.h:68
@ SPAWN_SUSPEND
Definition proc.h:61
@ SPAWN_COPY_NS
Don't share the parent's namespace, instead create a new copy of it.
Definition proc.h:67
@ SPAWN_EMPTY_ENV
Don't inherit the parent's environment variables.
Definition proc.h:64
@ SPAWN_EMPTY_CWD
Don't inherit the parent's current working directory, starts at root (/).
Definition proc.h:65
@ PROT_READ
Readable memory.
Definition proc.h:124
@ PROT_EXECUTE
Executable memory.
Definition proc.h:126
@ PROT_WRITE
Writable memory.
Definition proc.h:125
@ PROT_NONE
Invalid memory, cannot be accessed.
Definition proc.h:123
__UINT64_TYPE__ tid_t
Thread Identifier.
Definition tid_t.h:12
__UINT64_TYPE__ fd_t
File descriptor type.
Definition fd_t.h:10
__UINT64_TYPE__ pid_t
Process Identifier.
Definition pid_t.h:11
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
static const path_flag_t flags[]
Definition path.c:47
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
__INT64_TYPE__ int64_t
Definition stdint.h:16
Synchronization object.
Definition proc.h:248
atomic_uint64_t value
The value of the sync object.
Definition proc.h:249