1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 10:37:41 +00:00

Kernel: Implement FUTEX_WAKE of arbitrary count.

Previously we just woke all waiters no matter how many were
requested. Fix this by implementing WaitQueue::wake_n(..).
This commit is contained in:
Brian Gianforcaro 2020-04-25 16:57:12 -07:00 committed by Andreas Kling
parent e8f6f655bf
commit 1f64e3eb16
3 changed files with 17 additions and 2 deletions

View file

@ -4636,8 +4636,7 @@ int Process::sys$futex(const Syscall::SC_futex_params* user_params)
if (value == 1) { if (value == 1) {
futex_queue(userspace_address).wake_one(); futex_queue(userspace_address).wake_one();
} else { } else {
// FIXME: Wake exactly (value) waiters. futex_queue(userspace_address).wake_n(value);
futex_queue(userspace_address).wake_all();
} }
break; break;
} }

View file

@ -55,6 +55,21 @@ void WaitQueue::wake_one(Atomic<bool>* lock)
Scheduler::stop_idling(); Scheduler::stop_idling();
} }
void WaitQueue::wake_n(i32 wake_count)
{
InterruptDisabler disabler;
if (m_threads.is_empty())
return;
for (i32 i = 0; i < wake_count; ++i) {
Thread* thread = m_threads.take_first();
if (!thread)
break;
thread->wake_from_queue();
}
Scheduler::stop_idling();
}
void WaitQueue::wake_all() void WaitQueue::wake_all()
{ {
InterruptDisabler disabler; InterruptDisabler disabler;

View file

@ -39,6 +39,7 @@ public:
void enqueue(Thread&); void enqueue(Thread&);
void wake_one(Atomic<bool>* lock = nullptr); void wake_one(Atomic<bool>* lock = nullptr);
void wake_n(i32 wake_count);
void wake_all(); void wake_all();
void clear(); void clear();