My Kernel v0.1.0
process.h
Go to the documentation of this file.
1#pragma once
2
34#include <kernel/file.h>
35#include <kernel/types.h>
36#include <kernel/user.h>
37#include <kernel/vmm.h>
38#include <kernel/signal.h>
39
40#include <libalgo/linked_list.h>
41#include <utils/compiler.h>
42
43#include <string.h>
44
45#if ARCH == i686
47#else
48#error Unsupported arcihtecture
49#endif
50
52#define PROCESS_NAME_MAX_LEN 32U
53
55#define PROCESS_FD_COUNT 32
56
57struct address_space;
58
65typedef void (*thread_entry_t)(void *data);
66
70typedef enum thread_state {
75} thread_state_t;
76
86struct process {
88 pid_t pid;
89 unsigned int flags;
90
91 struct address_space *as;
93 struct process *parent;
97 node_t this;
100 size_t refcount;
112 /*
113 * Signal handling.
114 */
115 struct signal_set *sig_set; /* Registered signal handlers. */
116 struct signal_queue sig_pending;
117 sig_sa_sigaction_t sig_handler; /* stub handler set by sigsethandler(). */
118
119 thread_state_t state;
120 uint16_t exit_status;
125};
126
127/*
128 * Possible values for (struct process)->flags.
129 */
130enum process_flags {
131 PROC_SA_NOCLDWAIT = BIT(0), /* Do not generate SIGCHLD when children stop */
132};
133
134/* Union of all the flags that should be inherited when forking. */
135#define PROC_FLAGS_INHERITED (PROC_SA_NOCLDWAIT)
136
149typedef struct thread {
150
158 thread_state_t state;
160 pid_t tid;
161 u32 flags;
163 struct process *process;
170 union {
172 struct {
173 clock_t wakeup;
175 };
176
177 /*
178 * Signal handling.
179 */
180 struct signal_queue sig_pending;
181 sigset_t sig_blocked; /* mask of currently blocked signals. */
182
183} thread_t;
184
185/*
186 * List of all processes and threads currently alive.
187 *
188 * These list only contain live threads/processes so that lookups
189 * do not return objects that have already been killed.
190 */
191extern llist_t processes_list;
192extern spinlock_t processes_list_lock;
193extern llist_t threads_list;
194extern spinlock_t threads_list_lock;
195
197typedef enum thread_flags {
200} process_flags_t;
201
202/***/
203static ALWAYS_INLINE bool thread_is_kernel(thread_t *thread)
204{
205 return thread->flags & THREAD_KERNEL;
206}
207
211static ALWAYS_INLINE bool thread_is_initial(thread_t *thread)
212{
213 return thread->tid == thread->process->pid;
214}
215
217static inline void thread_set_stack_pointer(struct thread *thread, void *stack)
218{
219 arch_thread_set_stack_pointer(&thread->context, stack);
220}
221
223static inline void *thread_get_stack_pointer(struct thread *thread)
224{
225 return arch_thread_get_stack_pointer(&thread->context);
226}
227
229static inline void thread_set_base_pointer(struct thread *thread, void *ptr)
230{
231 arch_thread_set_base_pointer(&thread->context, ptr);
232}
233
235static inline void *thread_get_base_pointer(struct thread *thread)
236{
237 return arch_thread_get_base_pointer(&thread->context);
238}
239
241static inline void
243 const struct interrupt_frame *frame)
244{
245 arch_thread_set_interrupt_frame(&thread->context, frame);
246}
247
249static inline struct interrupt_frame *
251{
252 return arch_thread_get_interrupt_frame(&thread->context);
253}
254
256static inline void thread_set_kernel_stack(struct thread *thread, void *stack)
257{
258 arch_thread_set_kernel_stack_top(&thread->context,
259 stack + KERNEL_STACK_SIZE);
260}
261
263static inline void *thread_get_kernel_stack_top(const struct thread *thread)
264{
265 return arch_thread_get_kernel_stack_top(&thread->context);
266}
267
269static inline void *thread_get_kernel_stack(const struct thread *thread)
270{
272 if (!top)
273 return NULL;
274
275 return top - KERNEL_STACK_SIZE;
276}
277
279static inline void thread_set_user_stack(struct thread *thread, void *stack)
280{
281 arch_thread_set_user_stack_top(&thread->context, stack + USER_STACK_SIZE);
282}
283
285static inline void *thread_get_user_stack_top(const struct thread *thread)
286{
287 return arch_thread_get_user_stack_top(&thread->context);
288}
289
291static inline void *thread_get_user_stack(const struct thread *thread)
292{
294 if (!top)
295 return NULL;
296
297 return top - USER_STACK_SIZE;
298}
299
303static inline void *
305{
306 return arch_thread_get_interrupt_return_address(&thread->context);
307}
308
317extern struct process kernel_process;
318extern struct thread kernel_process_initial_thread;
319
327extern struct process *init_process;
328
336
338void process_kill(struct process *process, uint16_t status);
339
343int process_register_file(struct process *, struct file *);
344
346error_t process_unregister_file(struct process *, int fd);
347
352struct file *process_file_get(struct process *, int fd);
353
355static inline void process_file_put(struct process *process, struct file *file)
356{
358 file_put(file);
359}
360
369struct thread *process_execute_in_userland(const char *exec_path);
370
371/***/
372static inline void process_set_name(struct process *process, const char *name,
373 size_t size)
374{
375 strlcpy(process->name, name, MIN(size + 1, PROCESS_NAME_MAX_LEN));
376}
377
379struct process *process_find_by_pid(pid_t pid);
380
382extern thread_t *current;
383
388bool thread_switch(thread_t *);
389
405thread_t *thread_spawn(struct process *, thread_entry_t, void *data,
406 void *esp, void *ebp, u32 flags);
407
423NO_RETURN void thread_jump_to_userland(void *stack_pointer, void *base_pointer,
424 thread_entry_t, void *);
425
430void thread_set_mmu(struct thread *thread, paddr_t mmu);
431
437void thread_kill(thread_t *);
438
450struct thread *thread_fork(struct thread *, thread_entry_t, void *);
451
457
459struct thread *thread_find_by_tid(pid_t tid);
460
static void file_put(struct file *file)
Decrement an open file description's reference count.
Definition: file.h:71
#define USER_STACK_SIZE
Definition: memory.h:59
#define KERNEL_STACK_SIZE
Definition: memory.h:55
struct file * process_file_get(struct process *, int fd)
Definition: process.c:473
static ALWAYS_INLINE bool thread_is_initial(thread_t *thread)
The initial thread is the thread created along with the process.
Definition: process.h:211
static void thread_set_user_stack(struct thread *thread, void *stack)
Set the thread's user stack bottom address.
Definition: process.h:279
static void * thread_get_interrupt_return_address(const struct thread *thread)
Read the thread's return address when exiting the current interrupt context.
Definition: process.h:304
struct thread * thread_fork(struct thread *, thread_entry_t, void *)
Create a new fork of the given thread.
Definition: process.c:699
void thread_set_mmu(struct thread *thread, paddr_t mmu)
Set the MMU address saved inside the thread's structure.
Definition: process.c:811
static void * thread_get_user_stack(const struct thread *thread)
Get the thread's user stack bottom address.
Definition: process.h:291
struct thread * process_execute_in_userland(const char *exec_path)
Run an executable.
Definition: process.c:681
static void * thread_get_stack_pointer(struct thread *thread)
Get the thread's current stack pointer.
Definition: process.h:223
thread_state
The different states a thread can be in.
Definition: process.h:70
static void * thread_get_base_pointer(struct thread *thread)
Get the thread's current base pointer.
Definition: process.h:235
struct process * init_process
The init process is the very first executed userland process.
Definition: process.c:108
#define PROCESS_NAME_MAX_LEN
The max length of a process's name.
Definition: process.h:52
static void * thread_get_kernel_stack(const struct thread *thread)
Get the thread's kernel stack bottom address.
Definition: process.h:269
error_t process_unregister_file(struct process *, int fd)
Remove an open file from the process's open file descriptor table.
Definition: process.c:455
static void thread_set_kernel_stack(struct thread *thread, void *stack)
Set the thread's kernel stack bottom address.
Definition: process.h:256
static struct interrupt_frame * thread_get_interrupt_frame(struct thread *thread)
Get a thread's current interrupt frame.
Definition: process.h:250
void(* thread_entry_t)(void *data)
A function used as an entry point when creating a new thread.
Definition: process.h:65
static void * thread_get_kernel_stack_top(const struct thread *thread)
Get the thread's kernel stack top address.
Definition: process.h:263
#define PROCESS_FD_COUNT
Maximum number of files that one process can have open at any one time.
Definition: process.h:55
static void thread_set_base_pointer(struct thread *thread, void *ptr)
Set the thread's current base pointer.
Definition: process.h:229
static void thread_set_stack_pointer(struct thread *thread, void *stack)
Set the thread's current stack pointer.
Definition: process.h:217
bool thread_switch(thread_t *)
Switch the currently running thread.
Definition: process.c:602
struct process kernel_process
Process used when starting up the kernel.
Definition: process.c:99
NO_RETURN void thread_jump_to_userland(void *stack_pointer, void *base_pointer, thread_entry_t, void *)
Start executing code in userland.
Definition: process.c:805
void thread_kill(thread_t *)
Effectively kill a thread.
Definition: process.c:649
struct process * process_find_by_pid(pid_t pid)
Find an alive process by its PID.
Definition: process.c:889
thread_t * current
The currently running thread.
Definition: process.c:106
struct thread * thread_find_by_tid(pid_t tid)
Find an alive thread by its TID.
Definition: process.c:907
static void process_file_put(struct process *process, struct file *file)
Release a file description retreived using process_file_get().
Definition: process.h:355
thread_flags
Definition: process.h:197
static void * thread_get_user_stack_top(const struct thread *thread)
Get the thread's user stack top address.
Definition: process.h:285
thread_t * thread_spawn(struct process *, thread_entry_t, void *data, void *esp, void *ebp, u32 flags)
Create and initialize a new thread.
Definition: process.c:490
void process_init_kernel_process(void)
Initialize the kernel process's address space.
Definition: process.c:373
static void thread_set_interrupt_frame(thread_t *thread, const struct interrupt_frame *frame)
Set a thread's curent interrupt frame.
Definition: process.h:242
void thread_deliver_pending_signal(struct thread *thread)
Try and deliver the first non-blocked pending signal.
Definition: process.c:925
void process_kill(struct process *process, uint16_t status)
Kill a process.
Definition: process.c:329
int process_register_file(struct process *, struct file *)
Register an open file inside the process's open file descriptor table.
Definition: process.c:435
@ SCHED_RUNNING
Currently running (or ready to run)
Definition: process.h:71
@ SCHED_KILLED
The thread has been killed waiting to be destroyed.
Definition: process.h:74
@ SCHED_ZOMBIE
Thread waiting to be collected by its parent process.
Definition: process.h:73
@ SCHED_WAITING
Currently waiting for a resource (timer, lock ...)
Definition: process.h:72
@ THREAD_KERNEL
This is a kernel thread.
Definition: process.h:198
@ THREAD_RESCHED
Reschedule when exiting interrupt.
Definition: process.h:199
#define BIT(_n)
Generate the nth power of 2 (nth bit set)
Definition: bits.h:20
#define MIN(_x, _y)
Compute the minimum value between 2 numbers.
Definition: math.h:27
#define UNUSED(_x)
Avoid compiler warning when not using a symbol.
Definition: macro.h:35
Address space.
Definition: vm.h:45
Opened file description.
Definition: file.h:45
Frame passed onto the interrupt handlers by our stub handler.
Definition: interrupts.h:118
The head of a doubly linked list.
Definition: linked_list.h:43
Intrusive doubly-linked list node.
Definition: linked_list.h:27
A single process.
Definition: process.h:86
struct user_creds * creds
Transmitted to the parent process during wait()
Definition: process.h:122
llist_t threads
Definition: process.h:94
spinlock_t files_lock
Definition: process.h:110
char name[PROCESS_NAME_MAX_LEN]
Definition: process.h:87
struct address_space * as
Definition: process.h:91
size_t refcount
Definition: process.h:100
spinlock_t lock
Process credentials.
Definition: process.h:124
node_t this_global
Definition: process.h:98
llist_t children
Definition: process.h:95
pid_t pid
Definition: process.h:88
struct file * files[PROCESS_FD_COUNT]
Open file descriptors table.
Definition: process.h:109
Spinlock.
Definition: spinlock.h:29
A single thread.
Definition: process.h:149
node_t this_proc
Definition: process.h:165
thread_state_t state
Definition: process.h:158
struct process * process
Definition: process.h:163
node_t this_sched
Definition: process.h:166
pid_t tid
Definition: process.h:160
clock_t wakeup
Definition: process.h:173
node_t this_global
Definition: process.h:167
struct thread::@9::@11 sleep
For sleeping threads only.
u32 flags
Definition: process.h:161
thread_context_t context
Arch specific thread context.
Definition: process.h:157
User credentials.
Definition: user.h:21
Contains all the system-level information about a task.
Definition: process.h:21
Userland control mechanisms.