mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user