diff options
-rw-r--r-- | Kernel/Lock.cpp | 9 | ||||
-rw-r--r-- | Kernel/Thread.cpp | 4 | ||||
-rw-r--r-- | Kernel/Thread.h | 3 | ||||
-rw-r--r-- | Kernel/WaitQueue.cpp | 4 | ||||
-rw-r--r-- | Kernel/WaitQueue.h | 3 |
5 files changed, 13 insertions, 10 deletions
diff --git a/Kernel/Lock.cpp b/Kernel/Lock.cpp index f1d0888dee..a9d7929495 100644 --- a/Kernel/Lock.cpp +++ b/Kernel/Lock.cpp @@ -18,8 +18,7 @@ void Lock::lock() m_lock.store(false, AK::memory_order_release); return; } - m_lock.store(false, AK::memory_order_release); - current->wait_on(m_queue, m_holder, m_name); + current->wait_on(m_queue, &m_lock, m_holder, m_name); } } } @@ -37,8 +36,7 @@ void Lock::unlock() return; } m_holder = nullptr; - m_queue.wake_one(); - m_lock.store(false, AK::memory_order_release); + m_queue.wake_one(&m_lock); return; } // I don't know *who* is using "m_lock", so just yield. @@ -66,8 +64,7 @@ bool Lock::unlock_if_locked() return false; } m_holder = nullptr; - m_lock.store(false, AK::memory_order_release); - m_queue.wake_one(); + m_queue.wake_one(&m_lock); return true; } // I don't know *who* is using "m_lock", so just yield. diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 31e15d17b9..7e63c88ef9 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -783,10 +783,12 @@ const LogStream& operator<<(const LogStream& stream, const Thread& value) return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")"; } -void Thread::wait_on(WaitQueue& queue, Thread* beneficiary, const char* reason) +void Thread::wait_on(WaitQueue& queue, Atomic<bool>* lock, Thread* beneficiary, const char* reason) { bool did_unlock = unlock_process_if_locked(); cli(); + if (lock) + *lock = false; set_state(State::Queued); queue.enqueue(*current); // Yield and wait for the queue to wake us up again. diff --git a/Kernel/Thread.h b/Kernel/Thread.h index c17b43bbba..18f8546464 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -1,5 +1,6 @@ #pragma once +#include <AK/Atomic.h> #include <AK/Function.h> #include <AK/IntrusiveList.h> #include <AK/OwnPtr.h> @@ -300,7 +301,7 @@ public: return block<ConditionBlocker>(state_string, move(condition)); } - void wait_on(WaitQueue& queue, Thread* beneficiary = nullptr, const char* reason = nullptr); + void wait_on(WaitQueue& queue, Atomic<bool>* lock = nullptr, Thread* beneficiary = nullptr, const char* reason = nullptr); void wake_from_queue(); void unblock(); diff --git a/Kernel/WaitQueue.cpp b/Kernel/WaitQueue.cpp index e3541e93f3..9ea2f9f50c 100644 --- a/Kernel/WaitQueue.cpp +++ b/Kernel/WaitQueue.cpp @@ -15,9 +15,11 @@ void WaitQueue::enqueue(Thread& thread) m_threads.append(thread); } -void WaitQueue::wake_one() +void WaitQueue::wake_one(Atomic<bool>* lock) { InterruptDisabler disabler; + if (lock) + *lock = false; if (m_threads.is_empty()) return; if (auto* thread = m_threads.take_first()) diff --git a/Kernel/WaitQueue.h b/Kernel/WaitQueue.h index ebe46702bf..81893af25a 100644 --- a/Kernel/WaitQueue.h +++ b/Kernel/WaitQueue.h @@ -1,5 +1,6 @@ #pragma once +#include <AK/Atomic.h> #include <AK/SinglyLinkedList.h> #include <Kernel/Thread.h> @@ -9,7 +10,7 @@ public: ~WaitQueue(); void enqueue(Thread&); - void wake_one(); + void wake_one(Atomic<bool>* lock = nullptr); void wake_all(); private: |