From 2a16c1f6f9118e7127d532421ae19b959b3f1d87 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sat, 20 Aug 2022 00:00:52 +0200 Subject: user/libc: don't access the old stack from the new thread at all --- src/user/app/tests/kernel/threads.c | 12 +++++++++- src/user/lib/thread.S | 46 +++++++++++++++++++++++++++++++------ src/user/lib/thread.c | 11 --------- src/user/lib/thread.h | 9 ++++++-- 4 files changed, 57 insertions(+), 21 deletions(-) delete mode 100644 src/user/lib/thread.c diff --git a/src/user/app/tests/kernel/threads.c b/src/user/app/tests/kernel/threads.c index 2964883..cb7111d 100644 --- a/src/user/app/tests/kernel/threads.c +++ b/src/user/app/tests/kernel/threads.c @@ -18,7 +18,6 @@ static void test_basic_thread(void) { test(global_n == 10); } - handle_t global_h; static void shared_handle(void *sem) { handle_t ends[2]; @@ -39,7 +38,18 @@ static void test_shared_handle(void) { test(!strcmp("Hello!", buf)); } +static void many_thread(void *arg) { + *(uint64_t*)arg += 10; +} +static void test_many_threads(void) { + uint64_t n = 0; + for (int i = 0; i < 10; i++) thread_create(0, many_thread, &n); + for (int i = 0; i < 10; i++) _syscall_await(); + test(n == 100); +} + void r_k_threads(void) { run_test(test_basic_thread); run_test(test_shared_handle); + run_test(test_many_threads); } diff --git a/src/user/lib/thread.S b/src/user/lib/thread.S index 3cd3500..1a27c30 100644 --- a/src/user/lib/thread.S +++ b/src/user/lib/thread.S @@ -1,8 +1,40 @@ +#define ASM_FILE 1 +#include +#include + .section .text -.global chstack -.type chstack, @function -// _Noreturn void chstack(void *arg, void (*fn)(void*), void *esp); -chstack: - mov %rdx, %rsp - call *%rsi - jmp 0 // "exit" +.global thread_creates +.type thread_creates, @function +// void thread_creates(int flags, void (*fn)(void*), void *arg, void *stack); +thread_creates: + push %r12 + push %r13 + push %r14 + + /* save fn, arg, stack */ + mov %rsi, %r12 + mov %rdx, %r13 + mov %rcx, %r14 + + mov %rdi, %rsi + or $(FORK_SHAREMEM | FORK_SHAREHANDLE), %rsi + mov $_SYSCALL_FORK, %rdi + xor %rdx, %rdx + syscall + + test %rax, %rax + jz 1f + /* in parent, return normally */ + pop %r14 + pop %r13 + pop %r12 + ret +1: /* in child */ + mov %r14, %rsp + mov %r13, %rdi + call *%r12 + + mov $_SYSCALL_EXIT, %rdi + xor %rsi, %rsi + syscall + hlt /* if all else fails... */ diff --git a/src/user/lib/thread.c b/src/user/lib/thread.c deleted file mode 100644 index f7353ad..0000000 --- a/src/user/lib/thread.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include -#include - -void thread_create(int flags, void (*fn)(void*), void *arg) { - if (!_syscall_fork(flags | FORK_SHAREMEM | FORK_SHAREHANDLE, NULL)) { - void *stack = malloc(4096); - chstack(arg, fn, stack + 4096); - } -} diff --git a/src/user/lib/thread.h b/src/user/lib/thread.h index 0d7376a..5a5ddc0 100644 --- a/src/user/lib/thread.h +++ b/src/user/lib/thread.h @@ -1,4 +1,9 @@ #pragma once +#include -void thread_create(int flags, void (*fn)(void*), void *arg); -_Noreturn void chstack(void *arg, void (*fn)(void*), void *esp); +void thread_creates(int flags, void (*fn)(void*), void *arg, void *stack); + +static inline void thread_create(int flags, void (*fn)(void*), void *arg) { + /* error checking is for WIMPS. */ + thread_creates(flags, fn, arg, malloc(4096) + 4096); +} -- cgit v1.2.3