#include <sys/queue.h>
#include <sys/handle.h>
#include <sys/ktimer.h>
#include <sys/waitchannel.h>
#include <sys/semaphore.h>
#include <sys/mutex.h>
#include <sys/cv.h>
#include <machine/pmap.h>
#include <machine/thread.h>
Go to the source code of this file.
|
typedef | TAILQ_HEAD (ProcessQueue, Process) ProcessQueue |
|
typedef | TAILQ_HEAD (ThreadQueue, Thread) ThreadQueue |
|
void | Thread_Init () |
|
void | Thread_InitAP () |
|
Process * | Process_Create (Process *parent, const char *title) |
|
Process * | Process_Lookup (uint64_t pid) |
|
void | Process_Retain (Process *proc) |
|
void | Process_Release (Process *proc) |
|
uint64_t | Process_Wait (Process *proc, uint64_t pid) |
|
Thread * | Thread_Create (Process *proc) |
|
Thread * | Thread_KThreadCreate (void(*f)(void *), void *arg) |
|
Thread * | Thread_UThreadCreate (Thread *oldThr, uint64_t rip, uint64_t arg) |
|
Thread * | Thread_Lookup (Process *proc, uint64_t tid) |
|
void | Thread_Retain (Thread *thr) |
|
void | Thread_Release (Thread *thr) |
|
uint64_t | Thread_Wait (Thread *thr, uint64_t tid) |
|
Thread * | Sched_Current () |
|
void | Sched_SetRunnable (Thread *thr) |
|
void | Sched_SetWaiting (Thread *thr) |
|
void | Sched_SetZombie (Thread *thr) |
|
void | Sched_Scheduler () |
|
void | Process_Dump (Process *proc) |
|
void | Thread_Dump (Thread *thr) |
|
void | Thread_InitArch (Thread *thr) |
|
void | Thread_SetupKThread (Thread *thr, void(*f)(), uintptr_t arg1, uintptr_t arg2, uintptr_t arg3) |
|
void | Thread_SetupUThread (Thread *thr, uint64_t rip, uint64_t arg) |
|
void | Thread_SwitchArch (Thread *oldthr, Thread *newthr) |
|
void | Handle_Init (Process *proc) |
|
void | Handle_Destroy (Process *proc) |
|
uint64_t | Handle_Add (Process *proc, Handle *handle) |
|
void | Handle_Remove (Process *proc, Handle *handle) |
|
Handle * | Handle_Lookup (Process *proc, uint64_t fd) |
|
int | Copy_In (uintptr_t fromuser, void *tokernel, uintptr_t len) |
|
int | Copy_Out (void *fromkernel, uintptr_t touser, uintptr_t len) |
|
int | Copy_StrIn (uintptr_t fromuser, void *tokernel, uintptr_t len) |
|
int | Copy_StrOut (void *fromkernel, uintptr_t touser, uintptr_t len) |
|
◆ PROC_STATE_NULL
#define PROC_STATE_NULL 0 |
◆ PROC_STATE_READY
#define PROC_STATE_READY 1 |
◆ PROC_STATE_ZOMBIE
#define PROC_STATE_ZOMBIE 2 |
◆ PROCESS_HANDLE_SLOTS
#define PROCESS_HANDLE_SLOTS 128 |
◆ PROCESS_TITLE_LENGTH
#define PROCESS_TITLE_LENGTH 128 |
◆ SCHED_STATE_NULL
#define SCHED_STATE_NULL 0 |
◆ SCHED_STATE_RUNNABLE
#define SCHED_STATE_RUNNABLE 1 |
◆ SCHED_STATE_RUNNING
#define SCHED_STATE_RUNNING 2 |
◆ SCHED_STATE_WAITING
#define SCHED_STATE_WAITING 3 |
◆ SCHED_STATE_ZOMBIE
#define SCHED_STATE_ZOMBIE 4 |
◆ TID_ANY
#define TID_ANY 0xFFFFFFFF |
◆ Process
◆ Thread
◆ Copy_In()
Copy_In –
Safely copy memory from userspace. Prevents userspace pointers from reading kernel memory.
Side effects: Kernel page fault may have occurred.
- Parameters
-
[in] | fromuser | User address to copy from. |
[in] | tokernel | Kernel address to copy to. |
[in] | len | Length of the data to copy. |
- Return values
-
EFAULT | if the address is invalid or causes a fault. |
Definition at line 34 of file copy.c.
35{
37 return 0;
38
39
41 kprintf(
"Copy_In: address exceeds userspace top\n");
43 }
44
45
47 kprintf(
"Copy_In: length exceeds userspace top\n");
49 }
50
52}
int copy_unsafe(void *to_addr, void *from_addr, uintptr_t len)
int kprintf(const char *fmt,...)
#define MEM_USERSPACE_TOP
◆ Copy_Out()
Copy_Out –
Safely copy memory to userspace. Prevents userspace pointers from writing kernel memory.
Side effects: Kernel page fault may have occurred.
- Parameters
-
[in] | fromkernel | Kernel address to copy from. |
[in] | touser | User address to copy to. |
[in] | len | Length of the data to copy. |
- Return values
-
EFAULT | if the address is invalid or causes a fault. |
Definition at line 70 of file copy.c.
71{
73 return 0;
74
75
77 kprintf(
"Copy_Out: address exceeds userspace top\n");
79 }
80
81
83 kprintf(
"Copy_Out: length exceeds userspace top\n");
85 }
86
88}
◆ Copy_StrIn()
Copy_StrIn –
Safely copy a string from userspace. Prevents userspace pointers from reading kernel memory.
Side effects: Kernel page fault may have occurred.
- Parameters
-
[in] | fromuser | User address to copy from. |
[in] | tokernel | Kernel address to copy to. |
[in] | len | Maximum string length. |
- Return values
-
EFAULT | if the address is invalid or causes a fault. |
Definition at line 106 of file copy.c.
107{
109 return 0;
110
111
113 kprintf(
"Copy_StrIn: address exceeds userspace top\n");
115 }
116
117
119 kprintf(
"Copy_StrIn: length exceeds userspace top\n");
121 }
122
124}
int copystr_unsafe(void *to_addr, void *from_addr, uintptr_t len)
◆ Copy_StrOut()
Copy_StrOut –
Safely copy a string to userspace. Prevents userspace pointers from writing kernel memory.
Side effects: Kernel page fault may have occurred.
- Parameters
-
[in] | fromkernel | Kernel address to copy from. |
[in] | touser | User address to copy to. |
[in] | len | Maximum string length. |
- Return values
-
EFAULT | if the address is invalid or causes a fault. |
Definition at line 142 of file copy.c.
143{
145 return 0;
146
147
149 kprintf(
"Copy_StrOut: address exceeds userspace top\n");
151 }
152
153
155 kprintf(
"Copy_StrOut: length exceeds userspace top\n");
157 }
158
160}
◆ Handle_Add()
Definition at line 47 of file handle.c.
48{
49 int slot;
50
54
56
58
60}
#define PROCESS_HANDLE_SLOTS
#define TAILQ_INSERT_HEAD(head, elm, field)
HandleQueue handles[PROCESS_HANDLE_SLOTS]
◆ Handle_Destroy()
void Handle_Destroy |
( |
Process * |
proc | ) |
|
Definition at line 33 of file handle.c.
34{
35 int i;
36 Handle *handle, *handle_tmp;
37
41 (handle->
close)(handle);
42 }
43 }
44}
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
#define TAILQ_REMOVE(head, elm, field)
◆ Handle_Init()
Definition at line 23 of file handle.c.
24{
25 int i;
26
29 }
30}
◆ Handle_Lookup()
Definition at line 71 of file handle.c.
72{
75
78 return handle;
79 }
80
82}
#define TAILQ_FOREACH(var, head, field)
◆ Handle_Remove()
◆ Process_Create()
Process_Create –
Create a process.
- Parameters
-
[in] | parent | Parent process. |
[in] | title | Process title. |
- Returns
- The newly created process.
Definition at line 50 of file process.c.
51{
53
54 if (!proc)
56
57 memset(proc, 0,
sizeof(*proc));
58
64
65 if (title) {
67 } else {
68 proc->
title[0] =
'\0';
69 }
70
75 }
77
79
82
84
86 if (parent) {
90 }
96
100
101 return proc;
102}
void CV_Init(CV *cv, const char *name)
void Handle_Init(Process *proc)
#define PROCESS_TITLE_LENGTH
void Slab_Free(Slab *slab, void *obj)
void * Slab_Alloc(Slab *slab) __attribute__((malloc))
#define MEM_USERSPACE_STKBASE
#define TAILQ_INSERT_TAIL(head, elm, field)
void Semaphore_Init(Semaphore *sema, int count, const char *name)
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
#define SPINLOCK_TYPE_NORMAL
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
char * strncpy(char *to, const char *from, size_t len)
void * memset(void *dst, int c, size_t len)
char title[PROCESS_TITLE_LENGTH]
Semaphore zombieSemaphore
ProcessQueue childrenList
void Mutex_Init(Mutex *mtx, const char *name)
◆ Process_Dump()
void Process_Dump |
( |
Process * |
proc | ) |
|
Definition at line 251 of file process.c.
252{
253 const char *stateStrings[] = {
254 "NULL",
255 "READY",
256 "ZOMBIE"
257 };
258
266}
◆ Process_Lookup()
Process_Lookup –
Lookup a process by PID and increment its reference count.
- Parameters
-
- Return values
-
- Returns
- Process that corresponds to the pid.
Definition at line 145 of file process.c.
146{
149
154 proc = p;
155 break;
156 }
157 }
159
160 return proc;
161}
void Process_Retain(Process *proc)
◆ Process_Release()
void Process_Release |
( |
Process * |
proc | ) |
|
Process_Release –
Decrement the reference count for a given process.
- Parameters
-
proc | Process to release a reference of. |
Definition at line 185 of file process.c.
186{
188 if (__sync_fetch_and_sub(&proc->
refCount, 1) == 1) {
190 }
191}
static void Process_Destroy(Process *proc)
◆ Process_Retain()
void Process_Retain |
( |
Process * |
proc | ) |
|
Process_Retain –
Increment the reference count for a given process.
- Parameters
-
proc | Process to retain a reference to. |
Definition at line 171 of file process.c.
172{
174 __sync_fetch_and_add(&proc->
refCount, 1);
175}
◆ Process_Wait()
Process_Wait –
Wait for a process to exit and then cleanup it's references. If the pid == 0, we wait for any process, otherwise we wait for a specific process.
- Parameters
-
[in] | proc | Parent process. |
[in] | pid | Optionally specify the pid of the process to wait on. |
- Return values
-
- Returns
- Exit status of the process that exited or crashed.
Definition at line 206 of file process.c.
207{
211
212
213
214
215
216
217
218
219
221 return (pid << 16);
222
223
225
226
232
235
237 }
239
240
242
244}
void Thread_Release(Thread *thr)
#define TAILQ_FIRST(head)
#define TAILQ_EMPTY(head)
#define SYSCALL_PACK(_errcode, _val)
void Process_Release(Process *proc)
◆ Sched_Current()
Sched_Current() –
Get the currently executing thread. This function retains a reference count and you must release the reference by calling Thread_Release.
- Returns
- Returns the current thread.
Definition at line 56 of file sched.c.
57{
59
62
64
65 return thr;
66}
void Thread_Retain(Thread *thr)
Thread * curProc[MAX_CPUS]
◆ Sched_Scheduler()
Sched_Scheduler –
Run our round robin scheduler to find the process and switch to it.
Definition at line 189 of file sched.c.
190{
193
195
196
198 if (!next) {
199
200
201
202
203
204
205
208 return;
209 }
212
217
221 }
222
224
226}
#define SCHED_STATE_RUNNING
#define SCHED_STATE_RUNNABLE
ThreadQueue runnableQueue
static void Sched_Switch(Thread *oldthr, Thread *newthr)
◆ Sched_SetRunnable()
void Sched_SetRunnable |
( |
Thread * |
thr | ) |
|
Sched_SetRunnable –
Set the thread to the runnable state and move it from the wait queue if necessary to the runnable queue.
- Parameters
-
[in] | thr | Thread to be set as runnable. |
Definition at line 77 of file sched.c.
78{
80
83
88 }
91
93}
#define SCHED_STATE_WAITING
UnixEpochNS KTime_GetEpochNS()
◆ Sched_SetWaiting()
void Sched_SetWaiting |
( |
Thread * |
thr | ) |
|
Sched_SetWaiting –
Set the thread to the waiting state and move it to the wait queue. The thread should be currently running.
- Parameters
-
[in] | thr | Thread to be set as waiting. |
Definition at line 104 of file sched.c.
◆ Sched_SetZombie()
void Sched_SetZombie |
( |
Thread * |
thr | ) |
|
Sched_SetZombie –
Set the thread to the zombie state and move it to the parent processes's zombie process queue. The thread should be currently running.
- Parameters
-
[in] | thr | Thread to be set as zombie. |
Definition at line 126 of file sched.c.
127{
129
130
131
132
134
136
146 }
147
148
149
150
151
155
159
162}
uint32_t Critical_Level()
#define PROC_STATE_ZOMBIE
#define SCHED_STATE_ZOMBIE
void Mutex_Unlock(Mutex *mtx)
void Mutex_Lock(Mutex *mtx)
◆ TAILQ_HEAD() [1/2]
typedef TAILQ_HEAD |
( |
ProcessQueue |
, |
|
|
Process |
|
|
) |
| |
◆ TAILQ_HEAD() [2/2]
typedef TAILQ_HEAD |
( |
ThreadQueue |
, |
|
|
Thread |
|
|
) |
| |
◆ Thread_Create()
Definition at line 96 of file thread.c.
97{
99
100 if (!thr)
102
103 memset(thr, 0,
sizeof(*thr));
104
106
112 }
113
115
124
128
130
131
132 return thr;
133}
void Thread_InitArch(Thread *thr)
void Process_Retain(Process *proc)
void * PAlloc_AllocPage()
#define MEM_USERSPACE_STKLEN
◆ Thread_Dump()
void Thread_Dump |
( |
Thread * |
thr | ) |
|
Definition at line 328 of file thread.c.
329{
330 const char *states[] = {
331 "NULL",
332 "RUNNABLE",
333 "RUNNING",
334 "WAITING",
335 "ZOMBIE"
336 };
337
338
350 }
351}
void Process_Dump(Process *proc)
◆ Thread_Init()
Definition at line 53 of file thread.c.
54{
56
59
62
66
68
69
71
72
76}
Process * Process_Create(Process *parent, const char *title)
Thread * Thread_Create(Process *proc)
ThreadQueue runnableQueue
Thread * curProc[MAX_CPUS]
void Slab_Init(Slab *slab, const char *name, uintptr_t objsz, uintptr_t align)
#define SPINLOCK_TYPE_RECURSIVE
◆ Thread_InitAP()
◆ Thread_InitArch()
void Thread_InitArch |
( |
Thread * |
thr | ) |
|
◆ Thread_KThreadCreate()
Thread * Thread_KThreadCreate |
( |
void(*)(void *) |
f, |
|
|
void * |
arg |
|
) |
| |
Definition at line 136 of file thread.c.
137{
139 if (!thr)
141
143
144 return thr;
145}
void Thread_SetupKThread(Thread *thr, void(*f)(), uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
◆ Thread_Lookup()
Thread_Lookup –
Lookup a thread by TID and increment its reference count.
- Parameters
-
[in] | proc | Process within which to find a specific thread. |
[in] | tid | Thread ID of the thread to find. |
- Return values
-
NULL | if the thread isn't found. |
Definition at line 229 of file thread.c.
230{
233
238 thr = t;
239 break;
240 }
241 }
243
244 return thr;
245}
void Thread_Retain(Thread *thr)
◆ Thread_Release()
void Thread_Release |
( |
Thread * |
thr | ) |
|
Thread_Release –
Decrement the reference count for a given thread.
Definition at line 265 of file thread.c.
266{
268 if (__sync_fetch_and_sub(&thr->
refCount, 1) == 1) {
270 }
271}
static void Thread_Destroy(Thread *thr)
◆ Thread_Retain()
void Thread_Retain |
( |
Thread * |
thr | ) |
|
Thread_Retain –
Increment the reference count for a given thread.
Definition at line 253 of file thread.c.
254{
256 __sync_fetch_and_add(&thr->
refCount, 1);
257}
◆ Thread_SetupKThread()
Definition at line 26 of file thread.c.
28{
29
33
34 tf = (
TrapFrame *)(stacktop -
sizeof(*tf));
37
38 memset(tf, 0,
sizeof(*tf));
39 memset(sf, 0,
sizeof(*sf));
40
41
42
45
55}
void ThreadKThreadEntry(TrapFrame *tf)
◆ Thread_SetupUThread()
Definition at line 75 of file thread.c.
76{
79}
static void ThreadEnterUserLevelCB(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
◆ Thread_SwitchArch()
Definition at line 84 of file thread.c.
85{
86
87
88
89
91 {
93 }
94
96 {
98 }
99
101
102
104
105
107}
void switchstack(uint64_t *oldrsp, uint64_t rsp)
TaskStateSegment64 TSS[MAX_CPUS]
static INLINE void fxrstor(struct XSAVEArea *xsa)
static INLINE void clts()
static INLINE void fxsave(struct XSAVEArea *xsa)
◆ Thread_UThreadCreate()
Definition at line 148 of file thread.c.
149{
152
153 if (!thr)
155
156 memset(thr, 0,
sizeof(*thr));
157
163 }
164
168
173
175
176
178
179
181
183
186
190
191 return thr;
192}
void Thread_SetupUThread(Thread *thr, uintptr_t rip, uintptr_t arg)
bool PMap_AllocMap(AS *as, uint64_t virt, uint64_t len, uint64_t flags)
◆ Thread_Wait()
Thread_Wait –
Wait for any thread (tid == TID_ANY) or a specific thread.
Definition at line 279 of file thread.c.
280{
283
285
288 if (!t) {
290 }
291
296 }
297
298
305 }
306 }
307
308 return 0;
309}
void Thread_Release(Thread *thr)