Kaynağa Gözat

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.
Andreas Kling 3 yıl önce
ebeveyn
işleme
09f0843716
1 değiştirilmiş dosya ile 12 ekleme ve 25 silme
  1. 12 25
      Kernel/Thread.cpp

+ 12 - 25
Kernel/Thread.cpp

@@ -331,36 +331,23 @@ void Thread::block(Kernel::Mutex& lock, SpinlockLocker<Spinlock>& lock_lock, u32
 
 u32 Thread::unblock_from_mutex(Kernel::Mutex& mutex)
 {
+    SpinlockLocker scheduler_lock(g_scheduler_lock);
     SpinlockLocker block_lock(m_block_lock);
+
+    VERIFY(!Processor::current_in_irq());
     VERIFY(m_blocking_mutex == &mutex);
+
+    dbgln_if(THREAD_DEBUG, "Thread {} unblocked from Mutex {}", *this, &mutex);
+
     auto requested_count = m_lock_requested_count;
-    block_lock.unlock();
 
-    auto do_unblock = [&]() {
-        SpinlockLocker scheduler_lock(g_scheduler_lock);
-        SpinlockLocker block_lock(m_block_lock);
-        VERIFY(m_blocking_mutex == &mutex);
-        VERIFY(!Processor::current_in_irq());
-        VERIFY(g_scheduler_lock.is_locked_by_current_processor());
-        VERIFY(m_block_lock.is_locked_by_current_processor());
-        VERIFY(m_blocking_mutex == &mutex);
-        dbgln_if(THREAD_DEBUG, "Thread {} unblocked from Mutex {}", *this, &mutex);
-        m_blocking_mutex = nullptr;
-        if (Thread::current() == this) {
-            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();
+    m_blocking_mutex = nullptr;
+    if (Thread::current() == this) {
+        set_state(Thread::State::Running);
+        return requested_count;
     }
+    VERIFY(m_state != Thread::State::Runnable && m_state != Thread::State::Running);
+    set_state(Thread::State::Runnable);
     return requested_count;
 }