threads work on linux!

This commit is contained in:
flysand7 2023-08-26 13:53:58 +11:00
parent be17cebb56
commit 71aa64a7d4
4 changed files with 30 additions and 33 deletions

View File

@ -2,7 +2,7 @@
bits 64
section .text
global _cia_clone
global _cia_start_thread
; flags, &stack[-2], &parent_tid, &child_tid, 0
@ -23,14 +23,15 @@ global _cia_clone
; 0 if returning as a parent
; 1 if returning as a child
; negative value if there was an error making the thread
_cia_clone:
_cia_start_thread:
mov r10, rcx
sub rsi, 8
; As a child thread we wanna return to the same place as the parent
mov rax, qword [rsp]
mov qword [rsi], rax
; ; Copy child tid ptr
; mov qword [rsi + 0], rcx
; Setup child stack
sub rsi, 24
mov rax, [rsp]
mov [rsi+16], rax
mov rax, [rsp+8]
mov [rsi+8], rax
mov [rsi], r9
; Call syscall right away, since the order of the first 5 arguments
; matches with the argument order of the function
mov rax, 56 ; SYS_CLONE
@ -38,5 +39,10 @@ _cia_clone:
; Check to see if we're child
test eax, eax
jnz .exit
; If child, jump to thread function
pop rax ; thread_fn
pop rdi ; ctx
call rax
hlt
.exit:
ret

View File

@ -1,13 +1,14 @@
// See src/tinyrt.h file for the interface this file implements
extern i64 _cia_clone(
extern i64 _cia_start_thread(
u64 flags,
void *stack_base,
int *parent_tid,
int *child_tid,
void *tls,
u64 stack_size
void (*thread_fn)(void *ctx),
void *ctx
);
_Noreturn static void _rt_program_exit(int code) {
@ -21,7 +22,7 @@ static _RT_Status _rt_thread_current(_RT_Thread *thread) {
static _RT_Status _rt_thread_create(_RT_Thread *thread, void (*thread_fn)(void *ctx), void *ctx) {
// Create the memory for stack
u64 mmap_prot = PROT_READ|PROT_WRITE;
u64 mmap_flags = MAP_PRIVATE|MAP_ANONYMOUS;
u64 mmap_flags = MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE;
u64 stack_size = 0x10000;
void *stack_base = sys_mmap(0, stack_size, mmap_prot, mmap_flags, -1, 0);
if((i64)stack_base < 0) {
@ -43,13 +44,10 @@ static _RT_Status _rt_thread_create(_RT_Thread *thread, void (*thread_fn)(void *
int *parent_tid = &temp_permanent_storage[1];
*child_tid = 1;
*parent_tid = 0;
i64 ret = _cia_clone(flags, stack, parent_tid, child_tid, 0, stack_size);
i64 ret = _cia_start_thread(flags, stack, parent_tid, child_tid, 0, thread_fn, ctx);
if(ret < 0) {
return _RT_ERROR_GENERIC;
}
if(!ret) {
thread_fn(ctx);
}
return _RT_STATUS_OK;
}

8
test.c
View File

@ -1,8 +0,0 @@
#define __USE_GNU
#include <sched.h>
#ifdef CLONE_FILES
#define MYMACRO 1
#endif

View File

@ -3,23 +3,24 @@
#include <stdlib.h>
#include <threads.h>
static void print_str(char *str) {
int str_len = 0;
while(str[str_len] != 0) {
++str_len;
}
fwrite(str, 1, str_len, stdout);
}
int thrd_func(void *arg) {
char string[] = "child thread: ok!\n";
fwrite(string, 1, sizeof string-1, stdout);
// exit(1);
print_str("child thread: ok!\n");
for(;;);
return 0;
}
int main() {
{char string[] = "main thread: before!\n";
fwrite(string, 1, sizeof string-1, stdout);}
print_str("main thread: before\n");
thrd_t thrd;
thrd_create(&thrd, thrd_func, NULL);
{char string[] = "main thread: after!\n";
fwrite(string, 1, sizeof string-1, stdout);}
for(;;);
print_str("main thread: after!\n");
return 0;
}