From b197fc40a7bec76e80bc364c1b080e340ef920e9 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 7 Aug 2021 13:28:18 +0200 Subject: [PATCH] Kernel: Port process thread lists to SpinLockProtectedValue I had to move the thread list out of the protected base area of Process so that it could live with its lock (which needs to be mutable). Ideally it would live in the protected area, so maybe we can figure out a way to do that later. --- Kernel/Process.cpp | 10 +++++---- Kernel/Process.h | 52 ++++++++++++++++++++++++++-------------------- Kernel/Thread.h | 3 +++ 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index b417b6d40d..55cce1afd0 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -856,8 +856,9 @@ bool Process::remove_thread(Thread& thread) ProtectedDataMutationScope scope { *this }; auto thread_cnt_before = m_thread_count.fetch_sub(1, AK::MemoryOrder::memory_order_acq_rel); VERIFY(thread_cnt_before != 0); - ScopedSpinLock thread_list_lock(m_thread_list_lock); - m_thread_list.remove(thread); + thread_list().with([&](auto& thread_list) { + thread_list.remove(thread); + }); return thread_cnt_before == 1; } @@ -865,8 +866,9 @@ bool Process::add_thread(Thread& thread) { ProtectedDataMutationScope scope { *this }; bool is_first = m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) == 0; - ScopedSpinLock thread_list_lock(m_thread_list_lock); - m_thread_list.append(thread); + thread_list().with([&](auto& thread_list) { + thread_list.append(thread); + }); return is_first; } diff --git a/Kernel/Process.h b/Kernel/Process.h index d060194a40..5e4d89c4e7 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -102,7 +102,6 @@ protected: mode_t m_umask { 022 }; VirtualAddress m_signal_trampoline; Atomic m_thread_count { 0 }; - IntrusiveList, &Thread::m_process_thread_list_node> m_thread_list; u8 m_termination_status { 0 }; u8 m_termination_signal { 0 }; }; @@ -724,9 +723,12 @@ public: const FileDescriptions& fds() const { return m_fds; } private: - FileDescriptions m_fds; + SpinLockProtectedValue& thread_list() { return m_thread_list; } + SpinLockProtectedValue const& thread_list() const { return m_thread_list; } - mutable RecursiveSpinLock m_thread_list_lock; + SpinLockProtectedValue m_thread_list; + + FileDescriptions m_fds; const bool m_is_kernel_process; Atomic m_state { State::Running }; @@ -818,25 +820,27 @@ inline void Process::for_each_child(Callback callback) template Callback> inline IterationDecision Process::for_each_thread(Callback callback) const { - ScopedSpinLock thread_list_lock(m_thread_list_lock); - for (auto& thread : m_thread_list) { - IterationDecision decision = callback(thread); - if (decision != IterationDecision::Continue) - return decision; - } - return IterationDecision::Continue; + return thread_list().with([&](auto& thread_list) -> IterationDecision { + for (auto& thread : thread_list) { + IterationDecision decision = callback(thread); + if (decision != IterationDecision::Continue) + return decision; + } + return IterationDecision::Continue; + }); } template Callback> inline IterationDecision Process::for_each_thread(Callback callback) { - ScopedSpinLock thread_list_lock(m_thread_list_lock); - for (auto& thread : m_thread_list) { - IterationDecision decision = callback(thread); - if (decision != IterationDecision::Continue) - return decision; - } - return IterationDecision::Continue; + return thread_list().with([&](auto& thread_list) -> IterationDecision { + for (auto& thread : thread_list) { + IterationDecision decision = callback(thread); + if (decision != IterationDecision::Continue) + return decision; + } + return IterationDecision::Continue; + }); } template Callback> @@ -875,18 +879,20 @@ inline void Process::for_each_child(Callback callback) template Callback> inline IterationDecision Process::for_each_thread(Callback callback) const { - ScopedSpinLock thread_list_lock(m_thread_list_lock); - for (auto& thread : m_thread_list) - callback(thread); + thread_list().with([&](auto& thread_list) { + for (auto& thread : thread_list) + callback(thread); + }); return IterationDecision::Continue; } template Callback> inline IterationDecision Process::for_each_thread(Callback callback) { - ScopedSpinLock thread_list_lock(m_thread_list_lock); - for (auto& thread : m_thread_list) - callback(thread); + thread_list().with([&](auto& thread_list) { + for (auto& thread : thread_list) + callback(thread); + }); return IterationDecision::Continue; } diff --git a/Kernel/Thread.h b/Kernel/Thread.h index 827199bd55..172e580fb7 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -1372,6 +1372,9 @@ private: void yield_and_release_relock_big_lock(); void yield_assuming_not_holding_big_lock(); void drop_thread_count(bool); + +public: + using ListInProcess = IntrusiveList, &Thread::m_process_thread_list_node>; }; AK_ENUM_BITWISE_OPERATORS(Thread::FileBlocker::BlockFlags);