mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-27 23:09:08 +00:00
Kernel+LibPthread+LibC: Add a naive futex and use it for pthread_cond_t
This patch implements a simple version of the futex (fast userspace mutex) API in the kernel and uses it to make the pthread_cond_t API's block instead of busily sched_yield(). An arbitrary userspace address is passed to the kernel as a "token" that identifies the futex and you can then FUTEX_WAIT and FUTEX_WAKE that specific userspace address. FUTEX_WAIT corresponds to pthread_cond_wait() and FUTEX_WAKE is used for pthread_cond_signal() and pthread_cond_broadcast(). I'm pretty sure I'm missing something in this implementation, but it's hopefully okay for a start. :^)
This commit is contained in:
parent
4b8b100b83
commit
4a8683ea68
Notes:
sideshowbarker
2024-07-19 10:40:17 +09:00
Author: https://github.com/awesomekling
Commit: 4a8683ea68
9 changed files with 99 additions and 55 deletions
|
@ -3807,3 +3807,47 @@ Thread& Process::any_thread()
|
|||
ASSERT(found_thread);
|
||||
return *found_thread;
|
||||
}
|
||||
|
||||
WaitQueue& Process::futex_queue(i32* userspace_address)
|
||||
{
|
||||
auto& queue = m_futex_queues.ensure((u32)userspace_address);
|
||||
if (!queue)
|
||||
queue = make<WaitQueue>();
|
||||
return *queue;
|
||||
}
|
||||
|
||||
int Process::sys$futex(const Syscall::SC_futex_params* params)
|
||||
{
|
||||
if (!validate_read_typed(params))
|
||||
return -EFAULT;
|
||||
|
||||
auto& [userspace_address, futex_op, value, timeout] = *params;
|
||||
|
||||
if (!validate_read_typed(userspace_address))
|
||||
return -EFAULT;
|
||||
|
||||
if (timeout && !validate_read_typed(timeout))
|
||||
return -EFAULT;
|
||||
|
||||
switch (futex_op) {
|
||||
case FUTEX_WAIT:
|
||||
if (*userspace_address != value)
|
||||
return -EAGAIN;
|
||||
// FIXME: This is supposed to be interruptible by a signal, but right now WaitQueue cannot be interrupted.
|
||||
// FIXME: Support timeout!
|
||||
current->wait_on(futex_queue(userspace_address));
|
||||
break;
|
||||
case FUTEX_WAKE:
|
||||
if (value == 0)
|
||||
return 0;
|
||||
if (value == 1) {
|
||||
futex_queue(userspace_address).wake_one();
|
||||
} else {
|
||||
// FIXME: Wake exactly (value) waiters.
|
||||
futex_queue(userspace_address).wake_all();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue