AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
thread.c
Go to the documentation of this file.
1
11
12#include <core/system.h>
13#include <core/arch.h>
14#include <core/string.h>
15#include <mm/pmap.h>
16#include <mm/vm.h>
17#include <sys/lock.h>
18#include <sys/proc.h>
19#include <sys/sched.h>
20#include <sys/uaccess.h>
21
22MALLOC_DEFINE(M_AARCH64_THREAD, "aarch64-thread", "aarch64 thread structure");
23MALLOC_DEFINE(M_KERN_STACK, "kern-stack", "kernel stack");
24
31{
32 struct aarch64_thread *arch = kmalloc(sizeof(struct aarch64_thread), &M_AARCH64_THREAD, M_ZERO);
33
34 if (!arch)
35 return NULL;
36
37 void *kstack = kmalloc(KERN_STACK_SIZE, &M_KERN_STACK, 0);
38
39 if (!kstack) {
40 kfree(arch);
41 return NULL;
42 }
43
46 return arch;
47}
48
51static void __attribute__((noreturn)) thread_spawn(void)
52{
53 struct aarch64_thread *arch = curthread->arch;
54
56 aarch64_jump_user(arch->pc, arch->sp, arch->x0, arch->x1, arch->x2, arch->kstack);
57}
58
59/*
60 * Starts running a thread for the first time, on its kernel stack. It
61 * doesn't return.
62 */
71
72/*
73 * Switches to a thread that ran before: it goes on from where it was
74 * switched away from. It doesn't return.
75 */
77{
78 struct aarch64_thread *arch = thread->arch;
79
82
83 /* signals are taken on the way back to user mode
84 * (aarch64_return_to_user()), not here: the thread goes on from where
85 * it was */
86 aarch64_ctx_load(&arch->ctx);
87}
88
89/*
90 * Sets up a new user thread, for `pthread_create()`.
91 */
92int arch_thread_create(struct thread *thread, uintptr_t stack, uintptr_t entry, uintptr_t uentry, uintptr_t arg)
93{
94 struct aarch64_thread *arch = aarch64_thread_new();
95
96 thread->arch = arch;
97
98 if (!arch)
99 return -ENOMEM;
100
101 arch->pc = entry;
102 arch->sp = stack & ~(uintptr_t) 15;
103 arch->x0 = uentry;
104 arch->x1 = arg;
105 return 0;
106}
107
108/*
109 * Sets up a kernel thread, which starts at `entry` on its kernel stack
110 * once it is switched to. If there's no memory, the thread's state stays
111 * NULL.
112 */
114{
115 struct aarch64_thread *arch = aarch64_thread_new();
116
117 thread->arch = arch;
118
119 if (!arch)
120 return;
121
122 /* it's switched to as if it had stopped at its start:
123 * aarch64_ctx_load() "returns" into it */
124 arch->ctx.lr = entry;
125 arch->ctx.sp = arch->kstack;
126 arch->ctx.fp = 0;
127}
128
129/*
130 * Frees a thread's aarch64 state and kernel stack. The thread must not be
131 * running on them.
132 */
134{
135 struct aarch64_thread *arch = thread->arch;
136
137 /* killed already */
138 if (!arch)
139 return;
140
142 kfree((void *) arch->kstack_base);
143 kfree(arch);
144 thread->arch = NULL;
145}
void aarch64_jump_user(uintptr_t pc, uintptr_t sp, uintptr_t x0, uintptr_t x1, uintptr_t x2, uintptr_t kstack)
void aarch64_ctx_load(struct aarch64_ctx *ctx)
void aarch64_goto(uintptr_t fn, uintptr_t sp)
#define KERN_STACK_SIZE
Definition arch.h:68
struct aarch64_thread * aarch64_thread_new(void)
Makes a thread's aarch64 state, with its kernel stack.
Definition thread.c:30
int arch_thread_create(struct thread *thread, uintptr_t stack, uintptr_t entry, uintptr_t uentry, uintptr_t arg)
Sets up a new user thread's CPU state and kernel stack, for pthread_create().
Definition thread.c:92
static void thread_spawn(void)
Runs a thread for the first time: lets go of the kernel lock, and drops to user mode.
Definition thread.c:51
void arch_kthread_create(struct thread *thread, uintptr_t entry)
Sets up a kernel thread's CPU state.
Definition thread.c:113
void arch_thread_switch(struct thread *thread)
Switches to a thread that has run before: its address space, its kernel stack, then where it stopped.
Definition thread.c:76
void arch_thread_kill(struct thread *thread)
Frees a thread's CPU state and kernel stack.
Definition thread.c:133
void arch_thread_spawn(struct thread *thread)
Runs a thread for the first time: switches to its address space and kernel stack, and starts it.
Definition thread.c:63
void aarch64_fpsimd_drop(struct thread *thread)
Throws away a thread's FP/SIMD state, when it goes or execs a new program, and the registers' values ...
Definition fpsimd.c:106
void aarch64_fpsimd_switch(struct thread *thread)
Gets the registers ready for a thread that is about to run: its use of them traps,...
Definition fpsimd.c:52
#define MALLOC_DEFINE(type, _name, _desc)
Definition kvmem.h:30
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
#define M_ZERO
Definition kvmem.h:26
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
void kernel_unlock(void)
Lets go of the kernel lock, for the next CPU waiting for it.
Definition lock.c:46
struct pmap * pmap_switch(struct pmap *pmap)
Switches this CPU to an address space's page tables.
Definition pmap.c:164
#define curthread
Definition sched.h:12
#define NULL
Definition stddef.h:27
__SIZE_TYPE__ uintptr_t
Definition stddef.h:12
uint64_t lr
Definition arch.h:16
uint64_t sp
Definition arch.h:17
uint64_t fp
Definition arch.h:15
A thread's aarch64 state (thread->arch).
Definition arch.h:25
uint64_t x1
Definition arch.h:37
uint64_t sp
Definition arch.h:37
struct aarch64_ctx ctx
Definition arch.h:29
uint64_t x0
Definition arch.h:37
uintptr_t kstack_base
Definition arch.h:27
uint64_t x2
Definition arch.h:37
uintptr_t kstack
Definition arch.h:26
uint64_t pc
Definition arch.h:37
struct vm_space vm_space
its address space
Definition proc.h:129
A thread.
Definition thread.h:23
void * arch
the architecture's own data: its registers, its kernel stack
Definition thread.h:84
struct proc * owner
its process
Definition thread.h:31
struct pmap * pmap
its page tables (the architecture's)
Definition vm.h:27