summaryrefslogtreecommitdiff
path: root/src/user/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib')
-rw-r--r--src/user/lib/thread.S46
-rw-r--r--src/user/lib/thread.c11
-rw-r--r--src/user/lib/thread.h9
3 files changed, 46 insertions, 20 deletions
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 <camellia/syscalls.h>
+#include <camellia/flags.h>
+
.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 <camellia/flags.h>
-#include <camellia/syscalls.h>
-#include <stdlib.h>
-#include <user/lib/thread.h>
-
-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 <stdlib.h>
-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);
+}