summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-03-11 14:12:55 +0100
committerAndreas Kling <kling@serenityos.org>2021-03-11 14:21:49 +0100
commit4916b5c1300573c4fca94a1c0caf3a757565add4 (patch)
tree874e1e3a4d246fc0da23189798d8f50f91071db5 /Kernel
parent1b2ea12062354657e195620ad947520406e98c0c (diff)
downloadserenity-4916b5c1300573c4fca94a1c0caf3a757565add4.zip
Kernel: Move process thread lists into protected data
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/ProcFS.cpp2
-rw-r--r--Kernel/Process.cpp2
-rw-r--r--Kernel/Process.h21
-rw-r--r--Kernel/Thread.h1
4 files changed, 22 insertions, 4 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp
index 7829b38e2f..675c3076f7 100644
--- a/Kernel/FileSystem/ProcFS.cpp
+++ b/Kernel/FileSystem/ProcFS.cpp
@@ -1344,7 +1344,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
auto process = Process::from_pid(pid);
if (!process)
return ENOENT;
- process->for_each_thread([&](Thread& thread) -> IterationDecision {
+ process->for_each_thread([&](const Thread& thread) -> IterationDecision {
int tid = thread.tid().value();
callback({ String::number(tid), to_identifier_with_stack(fsid(), tid), 0 });
return IterationDecision::Continue;
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 0a01642a2d..3d74cf4dee 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -693,6 +693,7 @@ bool Process::create_perf_events_buffer_if_needed()
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);
@@ -702,6 +703,7 @@ bool Process::remove_thread(Thread& thread)
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);
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 0b6be73611..a1f37a3d93 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -119,6 +119,8 @@ protected:
u32 m_execpromises { 0 };
mode_t m_umask { 022 };
VirtualAddress m_signal_trampoline;
+ Atomic<u32> m_thread_count { 0 };
+ IntrusiveList<Thread, &Thread::m_process_thread_list_node> m_thread_list;
};
class ProcessBase : public ProtectedProcessBase {
@@ -245,8 +247,11 @@ public:
static void for_each_in_pgrp(ProcessGroupID, Callback);
template<typename Callback>
void for_each_child(Callback);
+
template<typename Callback>
- IterationDecision for_each_thread(Callback) const;
+ IterationDecision for_each_thread(Callback);
+ template<typename Callback>
+ IterationDecision for_each_thread(Callback callback) const;
void die();
void finalize();
@@ -576,8 +581,6 @@ private:
u8 m_termination_status { 0 };
u8 m_termination_signal { 0 };
- Atomic<u32> m_thread_count { 0 };
- mutable IntrusiveList<Thread, &Thread::m_process_thread_list_node> m_thread_list;
mutable RecursiveSpinLock m_thread_list_lock;
const bool m_is_kernel_process;
@@ -670,6 +673,18 @@ inline IterationDecision Process::for_each_thread(Callback callback) const
}
template<typename 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;
+}
+
+template<typename Callback>
inline void Process::for_each_in_pgrp(ProcessGroupID pgid, Callback callback)
{
VERIFY_INTERRUPTS_DISABLED();
diff --git a/Kernel/Thread.h b/Kernel/Thread.h
index 71c6e1526d..19176e136c 100644
--- a/Kernel/Thread.h
+++ b/Kernel/Thread.h
@@ -86,6 +86,7 @@ class Thread
AK_MAKE_NONMOVABLE(Thread);
friend class Process;
+ friend class ProtectedProcessBase;
friend class Scheduler;
friend class ThreadReadyQueue;