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

View File

@ -1,13 +1,14 @@
// See src/tinyrt.h file for the interface this file implements // See src/tinyrt.h file for the interface this file implements
extern i64 _cia_clone( extern i64 _cia_start_thread(
u64 flags, u64 flags,
void *stack_base, void *stack_base,
int *parent_tid, int *parent_tid,
int *child_tid, int *child_tid,
void *tls, void *tls,
u64 stack_size void (*thread_fn)(void *ctx),
void *ctx
); );
_Noreturn static void _rt_program_exit(int code) { _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) { static _RT_Status _rt_thread_create(_RT_Thread *thread, void (*thread_fn)(void *ctx), void *ctx) {
// Create the memory for stack // Create the memory for stack
u64 mmap_prot = PROT_READ|PROT_WRITE; 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; u64 stack_size = 0x10000;
void *stack_base = sys_mmap(0, stack_size, mmap_prot, mmap_flags, -1, 0); void *stack_base = sys_mmap(0, stack_size, mmap_prot, mmap_flags, -1, 0);
if((i64)stack_base < 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]; int *parent_tid = &temp_permanent_storage[1];
*child_tid = 1; *child_tid = 1;
*parent_tid = 0; *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) { if(ret < 0) {
return _RT_ERROR_GENERIC; return _RT_ERROR_GENERIC;
} }
if(!ret) {
thread_fn(ctx);
}
return _RT_STATUS_OK; 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 <stdlib.h>
#include <threads.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) { int thrd_func(void *arg) {
char string[] = "child thread: ok!\n"; print_str("child thread: ok!\n");
fwrite(string, 1, sizeof string-1, stdout);
// exit(1);
for(;;); for(;;);
return 0; return 0;
} }
int main() { int main() {
{char string[] = "main thread: before!\n"; print_str("main thread: before\n");
fwrite(string, 1, sizeof string-1, stdout);}
thrd_t thrd; thrd_t thrd;
thrd_create(&thrd, thrd_func, NULL); thrd_create(&thrd, thrd_func, NULL);
print_str("main thread: after!\n");
{char string[] = "main thread: after!\n";
fwrite(string, 1, sizeof string-1, stdout);}
for(;;);
return 0; return 0;
} }