1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 12:15:07 +00:00

LibPthread: implicitly call pthread_exit on return from start routine.

Previously, when returning from a pthread's start_routine, we would
segfault. Now we instead implicitly call pthread_exit as specified in
the standard.

pthread_create now creates a thread running the new
pthread_create_helper, which properly manages the calling and exiting
of the start_routine supplied to pthread_create. To accomplish this,
the thread's stack initialization has been moved out of
sys$create_thread and into the userspace function create_thread.
This commit is contained in:
Drew Stratford 2020-04-25 22:20:44 +12:00 committed by Andreas Kling
parent 4cb765e520
commit 4a37362249
3 changed files with 32 additions and 8 deletions

View file

@ -50,9 +50,37 @@ constexpr size_t highest_reasonable_stack_size = 8 * MB; // That's the default i
extern "C" {
static int create_thread(void* (*entry)(void*), void* argument, void* thread_params)
static void* pthread_create_helper(void* (*routine)(void*), void* argument)
{
return syscall(SC_create_thread, entry, argument, thread_params);
void* ret_val = routine(argument);
pthread_exit(ret_val);
return nullptr;
}
static int create_thread(void* (*entry)(void*), void* argument, PthreadAttrImpl* thread_params)
{
void** stack = (void**)((uintptr_t)thread_params->m_stack_location + thread_params->m_stack_size);
auto push_on_stack = [&](void* data) {
stack--;
*stack = data;
thread_params->m_stack_size -= sizeof(void*);
};
// We set up the stack for pthread_create_helper.
// Note that we need to align the stack to 16B, accounting for
// the fact that we also push 8 bytes.
while (((uintptr_t)stack - 8) % 16 != 0)
push_on_stack(nullptr);
push_on_stack(argument);
push_on_stack((void*)entry);
ASSERT((uintptr_t)stack % 16 == 0);
// Push a fake return address
push_on_stack(nullptr);
return syscall(SC_create_thread, pthread_create_helper, thread_params);
}
static void exit_thread(void* code)