1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:58:12 +00:00

Kernel: Allow unlocking a held Lock with interrupts disabled

This is needed to eliminate a race in Thread::wait_on() where we'd
otherwise have to wait until after unlocking the process lock before
we can disable interrupts.
This commit is contained in:
Andreas Kling 2020-01-12 22:53:20 +01:00
parent 2a8de4cdec
commit 65cb406327
4 changed files with 18 additions and 33 deletions

View file

@ -44,30 +44,15 @@ void Lock::unlock()
}
}
bool Lock::unlock_if_locked()
bool Lock::force_unlock_if_locked()
{
for (;;) {
bool expected = false;
if (m_lock.compare_exchange_strong(expected, true, AK::memory_order_acq_rel)) {
if (m_level == 0) {
m_lock.store(false, AK::memory_order_release);
return false;
}
if (m_holder != current) {
m_lock.store(false, AK::memory_order_release);
return false;
}
ASSERT(m_level);
--m_level;
if (m_level) {
m_lock.store(false, AK::memory_order_release);
return false;
}
m_holder = nullptr;
m_queue.wake_one(&m_lock);
return true;
}
// I don't know *who* is using "m_lock", so just yield.
Scheduler::yield();
}
InterruptDisabler disabler;
if (m_holder != current)
return false;
ASSERT(m_level == 1);
ASSERT(m_holder == current);
m_holder = nullptr;
--m_level;
m_queue.wake_one();
return true;
}