From 71aa64a7d4ec3242cb623e6fc1388ee22a7ff62a Mon Sep 17 00:00:00 2001 From: flysand7 Date: Sat, 26 Aug 2023 13:53:58 +1100 Subject: [PATCH] threads work on linux! --- arch/sysv_x86-64/thread-entry.asm | 22 ++++++++++++++-------- os/linux/tinyrt.c | 12 +++++------- test.c | 8 -------- tests/threaded.c | 21 +++++++++++---------- 4 files changed, 30 insertions(+), 33 deletions(-) delete mode 100644 test.c diff --git a/arch/sysv_x86-64/thread-entry.asm b/arch/sysv_x86-64/thread-entry.asm index 6605efb..df61895 100644 --- a/arch/sysv_x86-64/thread-entry.asm +++ b/arch/sysv_x86-64/thread-entry.asm @@ -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 diff --git a/os/linux/tinyrt.c b/os/linux/tinyrt.c index 9c40c8d..16ffe90 100644 --- a/os/linux/tinyrt.c +++ b/os/linux/tinyrt.c @@ -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; } diff --git a/test.c b/test.c deleted file mode 100644 index 692a89e..0000000 --- a/test.c +++ /dev/null @@ -1,8 +0,0 @@ - -#define __USE_GNU - -#include - -#ifdef CLONE_FILES - #define MYMACRO 1 -#endif diff --git a/tests/threaded.c b/tests/threaded.c index 8623306..9761e63 100644 --- a/tests/threaded.c +++ b/tests/threaded.c @@ -3,23 +3,24 @@ #include #include +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; }