mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 03:58:12 +00:00
Kernel: Enforce that Thread::unblock_from_mutex() doesn't happen in IRQ
Mutexes are not usable from IRQ handlers, so unblock_from_mutex() can simply VERIFY() that the current processor is not in an IRQ.
This commit is contained in:
parent
b0e5406ae2
commit
09f0843716
1 changed files with 14 additions and 27 deletions
|
@ -331,36 +331,23 @@ void Thread::block(Kernel::Mutex& lock, SpinlockLocker<Spinlock>& lock_lock, u32
|
||||||
|
|
||||||
u32 Thread::unblock_from_mutex(Kernel::Mutex& mutex)
|
u32 Thread::unblock_from_mutex(Kernel::Mutex& mutex)
|
||||||
{
|
{
|
||||||
|
SpinlockLocker scheduler_lock(g_scheduler_lock);
|
||||||
SpinlockLocker block_lock(m_block_lock);
|
SpinlockLocker block_lock(m_block_lock);
|
||||||
VERIFY(m_blocking_mutex == &mutex);
|
|
||||||
auto requested_count = m_lock_requested_count;
|
|
||||||
block_lock.unlock();
|
|
||||||
|
|
||||||
auto do_unblock = [&]() {
|
VERIFY(!Processor::current_in_irq());
|
||||||
SpinlockLocker scheduler_lock(g_scheduler_lock);
|
VERIFY(m_blocking_mutex == &mutex);
|
||||||
SpinlockLocker block_lock(m_block_lock);
|
|
||||||
VERIFY(m_blocking_mutex == &mutex);
|
dbgln_if(THREAD_DEBUG, "Thread {} unblocked from Mutex {}", *this, &mutex);
|
||||||
VERIFY(!Processor::current_in_irq());
|
|
||||||
VERIFY(g_scheduler_lock.is_locked_by_current_processor());
|
auto requested_count = m_lock_requested_count;
|
||||||
VERIFY(m_block_lock.is_locked_by_current_processor());
|
|
||||||
VERIFY(m_blocking_mutex == &mutex);
|
m_blocking_mutex = nullptr;
|
||||||
dbgln_if(THREAD_DEBUG, "Thread {} unblocked from Mutex {}", *this, &mutex);
|
if (Thread::current() == this) {
|
||||||
m_blocking_mutex = nullptr;
|
set_state(Thread::State::Running);
|
||||||
if (Thread::current() == this) {
|
return requested_count;
|
||||||
set_state(Thread::State::Running);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
VERIFY(m_state != Thread::State::Runnable && m_state != Thread::State::Running);
|
|
||||||
set_state(Thread::State::Runnable);
|
|
||||||
};
|
|
||||||
if (Processor::current_in_irq() != 0) {
|
|
||||||
Processor::deferred_call_queue([do_unblock = move(do_unblock), self = make_weak_ptr()]() {
|
|
||||||
if (auto this_thread = self.strong_ref())
|
|
||||||
do_unblock();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
do_unblock();
|
|
||||||
}
|
}
|
||||||
|
VERIFY(m_state != Thread::State::Runnable && m_state != Thread::State::Running);
|
||||||
|
set_state(Thread::State::Runnable);
|
||||||
return requested_count;
|
return requested_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue