diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index fe8c6459a6..ed5ce0eb0c 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -243,8 +243,8 @@ void Thread::consider_unblock(time_t now_sec, long now_usec) /* don't know, don't care */ return; case Thread::Blocked: - ASSERT(!m_blockers.is_empty()); - if (m_blockers.first()->should_unblock(*this, now_sec, now_usec)) + ASSERT(m_blocker != nullptr); + if (m_blocker->should_unblock(*this, now_sec, now_usec)) unblock(); return; case Thread::Skip1SchedulerPass: @@ -329,8 +329,8 @@ bool Scheduler::pick_next() return IterationDecision::Continue; if (was_blocked) { dbgprintf("Unblock %s(%u) due to signal\n", thread.process().name().characters(), thread.pid()); - ASSERT(!thread.m_blockers.is_empty()); - thread.m_blockers.first()->set_interrupted_by_signal(); + ASSERT(thread.m_blocker != nullptr); + thread.m_blocker->set_interrupted_by_signal(); thread.unblock(); } return IterationDecision::Continue; diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index e0a22ce71f..1a18f42f3e 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -179,8 +179,8 @@ const char* Thread::state_string() const case Thread::Skip0SchedulerPasses: return "Skip0"; case Thread::Blocked: - ASSERT(!m_blockers.is_empty()); - return m_blockers.first()->state_string(); + ASSERT(m_blocker != nullptr); + return m_blocker->state_string(); } kprintf("Thread::state_string(): Invalid state: %u\n", state()); ASSERT_NOT_REACHED(); @@ -576,7 +576,7 @@ void Thread::set_state(State new_state) InterruptDisabler disabler; if (new_state == Blocked) { // we should always have a Blocker while blocked - ASSERT(!m_blockers.is_empty()); + ASSERT(m_blocker != nullptr); } m_state = new_state; diff --git a/Kernel/Thread.h b/Kernel/Thread.h index 57f2732548..1f87ad7471 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -81,7 +81,6 @@ public: private: bool m_was_interrupted_while_blocked { false }; friend class Thread; - IntrusiveListNode m_blocker_list_node; }; class FileDescriptionBlocker : public Blocker { @@ -232,9 +231,10 @@ public: { // We should never be blocking a blocked (or otherwise non-active) thread. ASSERT(state() == Thread::Running); + ASSERT(m_blocker == nullptr); T t(AK::forward(args)...); - m_blockers.prepend(t); + m_blocker = &t; // Enter blocked state. set_state(Thread::Blocked); @@ -245,20 +245,8 @@ public: // We should no longer be blocked once we woke up ASSERT(state() != Thread::Blocked); - // We should be the first blocker, otherwise we're waking up in a - // different order than we are waiting: scheduler bug? - ASSERT(m_blockers.first() == &t); - // Remove ourselves... - m_blockers.remove(t); - - // If there are still pending blockers that need to be waited for, then - // set state back to Blocked, for the next one to be handled. - // Otherwise, we're good now, and done with blocking state. - if (!m_blockers.is_empty()) { - if (!m_blockers.first()->was_interrupted_by_signal()) - set_state(Thread::Blocked); - } + m_blocker = nullptr; if (t.was_interrupted_by_signal()) return BlockResult::InterruptedBySignal; @@ -343,7 +331,7 @@ private: RefPtr m_kernel_stack_region; VirtualAddress m_thread_specific_data; SignalActionData m_signal_action_data[32]; - IntrusiveList m_blockers; + Blocker* m_blocker { nullptr }; FPUState* m_fpu_state { nullptr }; State m_state { Invalid }; bool m_has_used_fpu { false };