Pārlūkot izejas kodu

Kernel+LibPthread: Add support for usermode threads on x86_64

Gunnar Beutner 4 gadi atpakaļ
vecāks
revīzija
16b9a2d2e1

+ 10 - 4
Kernel/API/Syscall.h

@@ -352,10 +352,16 @@ struct SC_create_thread_params {
     // a call to pthread_attr_getguardsize() specifying attr shall store in the guardsize
     // parameter the guard size specified by the previous pthread_attr_setguardsize() function call"
     // ... ok, if you say so posix. Guess we get to lie to people about guard page size
-    unsigned int m_guard_page_size = 0;          // Rounded up to PAGE_SIZE
-    unsigned int m_reported_guard_page_size = 0; // The lie we tell callers
-    unsigned int m_stack_size = 4 * MiB;         // Default PTHREAD_STACK_MIN
-    void* m_stack_location;                      // nullptr means any, o.w. process virtual address
+    unsigned int guard_page_size = 0;          // Rounded up to PAGE_SIZE
+    unsigned int reported_guard_page_size = 0; // The lie we tell callers
+    unsigned int stack_size = 4 * MiB;         // Default PTHREAD_STACK_MIN
+    void* stack_location;                      // nullptr means any, o.w. process virtual address
+#    if ARCH(X86_64)
+    FlatPtr rdi;
+    FlatPtr rsi;
+    FlatPtr rcx;
+    FlatPtr rdx;
+#    endif
 };
 
 struct SC_realpath_params {

+ 4 - 4
Kernel/Syscalls/thread.cpp

@@ -70,6 +70,10 @@ KResultOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<c
     regs.rip = (FlatPtr)entry;
     regs.rflags = 0x0202;
     regs.rsp = user_sp.value();
+    regs.rdi = params.rdi;
+    regs.rsi = params.rsi;
+    regs.rdx = params.rdx;
+    regs.rcx = params.rcx;
 #endif
     regs.cr3 = space().page_directory().cr3();
 
@@ -81,11 +85,7 @@ KResultOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<c
 
     ScopedSpinLock lock(g_scheduler_lock);
     thread->set_priority(requested_thread_priority);
-#if ARCH(I386)
     thread->set_state(Thread::State::Runnable);
-#else
-    dbgln("FIXME: Not starting thread {} (because it'd crash)", *thread);
-#endif
     return thread->tid().value();
 }
 

+ 7 - 0
Userland/Libraries/LibPthread/pthread.cpp

@@ -71,10 +71,17 @@ static int create_thread(pthread_t* thread, void* (*entry)(void*), void* argumen
     while (((uintptr_t)stack - 16) % 16 != 0)
         push_on_stack(nullptr);
 
+#if ARCH(I386)
     push_on_stack((void*)(uintptr_t)thread_params->stack_size);
     push_on_stack(thread_params->stack_location);
     push_on_stack(argument);
     push_on_stack((void*)entry);
+#else
+    thread_params->rdi = (FlatPtr)entry;
+    thread_params->rsi = (FlatPtr)argument;
+    thread_params->rdx = (FlatPtr)thread_params->stack_location;
+    thread_params->rcx = thread_params->stack_size;
+#endif
     VERIFY((uintptr_t)stack % 16 == 0);
 
     // Push a fake return address