mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
Kernel: Release big lock when blocking on another lock
When blocking on a Lock other than the big lock and we're holding the big lock, we need to release the big lock first. This fixes some deadlocks where a thread blocks while holding the big lock, preventing other threads from getting the big lock in order to unblock the waiting thread.
This commit is contained in:
parent
710cf14c55
commit
0536a4ff41
Notes:
sideshowbarker
2024-07-18 08:55:31 +09:00
Author: https://github.com/tomuta Commit: https://github.com/SerenityOS/serenity/commit/0536a4ff413 Pull-request: https://github.com/SerenityOS/serenity/pull/8791 Issue: https://github.com/SerenityOS/serenity/issues/8787
1 changed files with 8 additions and 1 deletions
|
@ -211,11 +211,18 @@ void Thread::block(Kernel::Lock& lock, ScopedSpinLock<SpinLock<u8>>& lock_lock,
|
|||
|
||||
dbgln_if(THREAD_DEBUG, "Thread {} blocking on Lock {}", *this, &lock);
|
||||
|
||||
auto& big_lock = process().big_lock();
|
||||
for (;;) {
|
||||
// Yield to the scheduler, and wait for us to resume unblocked.
|
||||
VERIFY(!g_scheduler_lock.own_lock());
|
||||
VERIFY(Processor::current().in_critical());
|
||||
yield_while_not_holding_big_lock(); // We might hold the big lock though!
|
||||
if (&lock != &big_lock && big_lock.own_lock()) {
|
||||
// We're locking another lock and already hold the big lock...
|
||||
// We need to release the big lock
|
||||
yield_without_holding_big_lock();
|
||||
} else {
|
||||
yield_while_not_holding_big_lock();
|
||||
}
|
||||
VERIFY(Processor::current().in_critical());
|
||||
|
||||
ScopedSpinLock block_lock2(m_block_lock);
|
||||
|
|
Loading…
Reference in a new issue