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:
parent
e8f6f655bf
commit
1f64e3eb16
3 changed files with 17 additions and 2 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue