summaryrefslogtreecommitdiff
path: root/Libraries/LibPthread
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-17 17:28:17 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-17 17:29:20 +0100
commite34ed04d1ee26e0b4e03d6c6b79b3ff195f9458c (patch)
tree60bad4a678f4f56bc14c7cb8e6f3793871860a58 /Libraries/LibPthread
parent6685be36a0c12dfd7e37fcba37afbc4facb6a49d (diff)
downloadserenity-e34ed04d1ee26e0b4e03d6c6b79b3ff195f9458c.zip
Kernel+LibPthread+LibC: Create secondary thread stacks in userspace
Have pthread_create() allocate a stack and passing it to the kernel instead of this work happening in the kernel. The more of this we can do in userspace, the better. This patch also unexposes the raw create_thread() and exit_thread() syscalls since they are now only used by LibPthread anyway.
Diffstat (limited to 'Libraries/LibPthread')
-rw-r--r--Libraries/LibPthread/pthread.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/Libraries/LibPthread/pthread.cpp b/Libraries/LibPthread/pthread.cpp
index b1e17b1f61..ba844ce400 100644
--- a/Libraries/LibPthread/pthread.cpp
+++ b/Libraries/LibPthread/pthread.cpp
@@ -1,18 +1,36 @@
+#include <AK/Assertions.h>
#include <AK/Atomic.h>
#include <AK/StdLibExtras.h>
#include <Kernel/Syscall.h>
#include <pthread.h>
-#include <unistd.h>
#include <stdio.h>
+#include <sys/mman.h>
+#include <unistd.h>
extern "C" {
+static int create_thread(void* (*entry)(void*), void* argument, void* stack)
+{
+ int rc = syscall(SC_create_thread, entry, argument, stack);
+ __RETURN_WITH_ERRNO(rc, rc, -1);
+}
+
+static void exit_thread(void* code)
+{
+ syscall(SC_exit_thread, code);
+ ASSERT_NOT_REACHED();
+}
+
int pthread_create(pthread_t* thread, pthread_attr_t* attributes, void* (*start_routine)(void*), void* argument_to_start_routine)
{
if (!thread)
return -EINVAL;
UNUSED_PARAM(attributes);
- int rc = create_thread(start_routine, argument_to_start_routine);
+ const size_t stack_size = 4 * MB;
+ auto* stack = (u8*)mmap_with_name(nullptr, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, 0, 0, "Thread stack");
+ if (!stack)
+ return -1;
+ int rc = create_thread(start_routine, argument_to_start_routine, stack + stack_size);
if (rc < 0)
return rc;
*thread = rc;
@@ -55,5 +73,4 @@ int pthread_mutex_unlock(pthread_mutex_t* mutex)
atomic->store(false, AK::memory_order_release);
return 0;
}
-
}