mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-06 16:45:03 +00:00
Kernel: Add a WaitQueue for Thread queueing/waking and use it for Lock
The kernel's Lock class now uses a proper wait queue internally instead of just having everyone wake up regularly to try to acquire the lock. We also keep the donation mechanism, so that whenever someone tries to take the lock and fails, that thread donates the remainder of its timeslice to the current lock holder. After unlocking a Lock, the unlocking thread calls WaitQueue::wake_one, which unblocks the next thread in queue.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include <Kernel/Lock.h>
|
||||
#include <Kernel/Thread.h>
|
||||
|
||||
void Lock::lock()
|
||||
{
|
||||
@@ -18,8 +19,8 @@ void Lock::lock()
|
||||
return;
|
||||
}
|
||||
m_lock.store(false, AK::memory_order_release);
|
||||
(void)current->donate_remaining_timeslice_and_block<Thread::WaitQueueBlocker>(m_holder, m_name, m_queue);
|
||||
}
|
||||
Scheduler::donate_to(m_holder, m_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,10 +37,12 @@ void Lock::unlock()
|
||||
return;
|
||||
}
|
||||
m_holder = nullptr;
|
||||
m_queue.wake_one();
|
||||
m_lock.store(false, AK::memory_order_release);
|
||||
return;
|
||||
}
|
||||
Scheduler::donate_to(m_holder, m_name);
|
||||
// I don't know *who* is using "m_lock", so just yield.
|
||||
Scheduler::yield();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +67,10 @@ bool Lock::unlock_if_locked()
|
||||
}
|
||||
m_holder = nullptr;
|
||||
m_lock.store(false, AK::memory_order_release);
|
||||
m_queue.wake_one();
|
||||
return true;
|
||||
}
|
||||
// I don't know *who* is using "m_lock", so just yield.
|
||||
Scheduler::yield();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user