[kernel] Add userspace threading

Implement the syscalls necessary for threads to create other threads in
their same process. This involved rearranging a number of syscalls, as
well as implementing object_wait and a basic implementation of a
process' list of handles.
This commit is contained in:
2020-07-26 16:02:38 -07:00
parent 4cf222a5bb
commit ae3290c53d
22 changed files with 481 additions and 255 deletions

View File

@@ -3,32 +3,53 @@
#include "j6/types.h"
#include "j6/errors.h"
#include "j6/signals.h"
extern "C" {
j6_status_t get_process_koid(j6_koid_t *koid);
j6_status_t sleep(uint64_t til);
j6_status_t debug();
j6_status_t message(const char *msg);
j6_status_t system_log(const char *msg);
j6_status_t object_wait(j6_handle_t obj, j6_signal_t sig, j6_signal_t *out);
j6_status_t process_koid(j6_koid_t *koid);
j6_status_t thread_koid(j6_koid_t *koid);
j6_status_t thread_create(void (*koid)(), j6_handle_t *handle);
j6_status_t thread_sleep(uint64_t til);
j6_status_t thread_exit(int64_t status);
int main(int, const char **);
}
void
thread_proc()
{
system_log("sub thread starting");
for (int i = 1; i < 5; ++i)
thread_sleep(i*10);
system_log("sub thread exiting");
thread_exit(0);
}
int
main(int argc, const char **argv)
{
uint64_t pid = 0;
uint64_t child = 0;
j6_koid_t process = 0;
j6_handle_t child = 0;
j6_signal_t out = 0;
j6_status_t result = get_process_koid(&process);
system_log("main thread starting");
j6_status_t result = thread_create(&thread_proc, &child);
if (result != j6_status_ok)
return result;
message("hello from nulldrv!");
system_log("main thread waiting on child");
for (int i = 1; i < 5; ++i)
sleep(i*10);
result = object_wait(child, -1ull, &out);
if (result != j6_status_ok)
return result;
return pid;
system_log("main thread done, exiting");
return 0;
}

View File

@@ -6,52 +6,30 @@ extern main
extern exit
section .text
global get_process_koid
get_process_koid:
push rbp
mov rbp, rsp
; address of out var should already be in rdi
mov rax, 0x10 ; getpid syscall
syscall ; result is now already in rax, so just return
%macro SYSCALL 2
global %1
%1:
push rbp
mov rbp, rsp
pop rbp
ret
; address of args should already be in rdi, etc
mov rax, %2
syscall
; result is now already in rax, so just return
global debug
debug:
push rbp
mov rbp, rsp
mov rax, 0x00 ; debug syscall
syscall
pop rbp
ret
global sleep
sleep:
push rbp
mov rbp, rsp
mov rax, 0x14 ; sleep syscall
syscall
pop rbp
ret
global message
message:
push rbp
mov rbp, rsp
; message should already be in rdi
mov rax, 0x12
syscall
pop rbp
ret
pop rbp
ret
%endmacro
SYSCALL system_log, 0x00
SYSCALL object_wait, 0x09
SYSCALL process_koid, 0x10
SYSCALL thread_koid, 0x18
SYSCALL thread_create, 0x19
SYSCALL thread_exit, 0x1a
SYSCALL thread_pause, 0x1b
SYSCALL thread_sleep, 0x1c
global _start
_start: