|
@@ -1,18 +1,36 @@
|
|
|
|
+#include <AK/Assertions.h>
|
|
#include <AK/Atomic.h>
|
|
#include <AK/Atomic.h>
|
|
#include <AK/StdLibExtras.h>
|
|
#include <AK/StdLibExtras.h>
|
|
#include <Kernel/Syscall.h>
|
|
#include <Kernel/Syscall.h>
|
|
#include <pthread.h>
|
|
#include <pthread.h>
|
|
-#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
|
|
+#include <sys/mman.h>
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
|
extern "C" {
|
|
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)
|
|
int pthread_create(pthread_t* thread, pthread_attr_t* attributes, void* (*start_routine)(void*), void* argument_to_start_routine)
|
|
{
|
|
{
|
|
if (!thread)
|
|
if (!thread)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
UNUSED_PARAM(attributes);
|
|
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)
|
|
if (rc < 0)
|
|
return rc;
|
|
return rc;
|
|
*thread = rc;
|
|
*thread = rc;
|
|
@@ -55,5 +73,4 @@ int pthread_mutex_unlock(pthread_mutex_t* mutex)
|
|
atomic->store(false, AK::memory_order_release);
|
|
atomic->store(false, AK::memory_order_release);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|