From d7ec5d042f60ce2a31569a75383eaa4551f86217 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Wed, 29 Dec 2021 00:46:21 +0200 Subject: [PATCH] Kernel: Port Process to ListedRefCounted --- Kernel/GlobalProcessExposed.cpp | 4 ++-- Kernel/Process.cpp | 32 ++++++-------------------------- Kernel/Process.h | 12 +++++------- Kernel/Syscalls/kill.cpp | 2 +- 4 files changed, 14 insertions(+), 36 deletions(-) diff --git a/Kernel/GlobalProcessExposed.cpp b/Kernel/GlobalProcessExposed.cpp index ea2f278cfe..6ddc661d27 100644 --- a/Kernel/GlobalProcessExposed.cpp +++ b/Kernel/GlobalProcessExposed.cpp @@ -534,7 +534,7 @@ private: { auto array = json.add_array("processes"); build_process(array, *Scheduler::colonel()); - processes().with([&](auto& processes) { + Process::all_instances().with([&](auto& processes) { for (auto& process : processes) build_process(array, process); }); @@ -942,7 +942,7 @@ ErrorOr ProcFSRootDirectory::traverse_as_directory(FileSystemID fsid, Func TRY(callback({ component.name(), identifier, 0 })); } - return processes().with([&](auto& list) -> ErrorOr { + return Process::all_instances().with([&](auto& list) -> ErrorOr { for (auto& process : list) { VERIFY(!(process.pid() < 0)); u64 process_id = (u64)process.pid().value(); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 3fa3e4d734..96d07ee458 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -43,7 +43,7 @@ static void create_signal_trampoline(); RecursiveSpinlock g_profiling_lock; static Atomic next_pid; -static Singleton> s_processes; +static Singleton> s_all_instances; READONLY_AFTER_INIT Memory::Region* g_signal_trampoline_region; static Singleton> s_hostname; @@ -53,9 +53,9 @@ MutexProtected& hostname() return *s_hostname; } -SpinlockProtected& processes() +SpinlockProtected& Process::all_instances() { - return *s_processes; + return *s_all_instances; } ProcessID Process::allocate_pid() @@ -123,7 +123,7 @@ void Process::register_new(Process& process) { // Note: this is essentially the same like process->ref() RefPtr new_process = process; - processes().with([&](auto& list) { + all_instances().with([&](auto& list) { list.prepend(process); }); } @@ -268,26 +268,6 @@ Process::~Process() PerformanceManager::add_process_exit_event(*this); } -bool Process::unref() const -{ - // NOTE: We need to obtain the process list lock before doing anything, - // because otherwise someone might get in between us lowering the - // refcount and acquiring the lock. - auto did_hit_zero = processes().with([&](auto& list) { - auto new_ref_count = deref_base(); - if (new_ref_count > 0) - return false; - - if (m_list_node.is_in_list()) - list.remove(*const_cast(this)); - return true; - }); - - if (did_hit_zero) - delete this; - return did_hit_zero; -} - // Make sure the compiler doesn't "optimize away" this function: extern void signal_trampoline_dummy() __attribute__((used)); void signal_trampoline_dummy() @@ -390,7 +370,7 @@ void Process::crash(int signal, FlatPtr ip, bool out_of_memory) RefPtr Process::from_pid(ProcessID pid) { - return processes().with([&](const auto& list) -> RefPtr { + return all_instances().with([&](const auto& list) -> RefPtr { for (auto const& process : list) { if (process.pid() == pid) return &process; @@ -690,7 +670,7 @@ void Process::die() m_threads_for_coredump.append(thread); }); - processes().with([&](const auto& list) { + all_instances().with([&](const auto& list) { for (auto it = list.begin(); it != list.end();) { auto& process = *it; ++it; diff --git a/Kernel/Process.h b/Kernel/Process.h index 81c699dc6a..ded36bdb78 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -86,7 +86,7 @@ using FutexQueues = HashMap>; struct LoadResult; class Process final - : public AK::RefCountedBase + : public ListedRefCounted , public Weakable { class ProtectedValues { @@ -183,7 +183,6 @@ public: static ErrorOr> try_create_user_process(RefPtr& first_thread, StringView path, UserID, GroupID, NonnullOwnPtrVector arguments, NonnullOwnPtrVector environment, TTY*); static void register_new(Process&); - bool unref() const; ~Process(); RefPtr create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true); @@ -808,6 +807,7 @@ private: public: using List = IntrusiveListRelaxedConst<&Process::m_list_node>; + static SpinlockProtected& all_instances(); }; // Note: Process object should be 2 pages of 4096 bytes each. @@ -818,13 +818,11 @@ static_assert(AssertSize()); extern RecursiveSpinlock g_profiling_lock; -SpinlockProtected& processes(); - template Callback> inline void Process::for_each(Callback callback) { VERIFY_INTERRUPTS_DISABLED(); - processes().with([&](const auto& list) { + Process::all_instances().with([&](const auto& list) { for (auto it = list.begin(); it != list.end();) { auto& process = *it; ++it; @@ -838,7 +836,7 @@ template Callback> inline void Process::for_each_child(Callback callback) { ProcessID my_pid = pid(); - processes().with([&](const auto& list) { + Process::all_instances().with([&](const auto& list) { for (auto it = list.begin(); it != list.end();) { auto& process = *it; ++it; @@ -879,7 +877,7 @@ inline IterationDecision Process::for_each_thread(Callback callback) template Callback> inline void Process::for_each_in_pgrp(ProcessGroupID pgid, Callback callback) { - processes().with([&](const auto& list) { + Process::all_instances().with([&](const auto& list) { for (auto it = list.begin(); it != list.end();) { auto& process = *it; ++it; diff --git a/Kernel/Syscalls/kill.cpp b/Kernel/Syscalls/kill.cpp index a9199153ab..5b9e3d5459 100644 --- a/Kernel/Syscalls/kill.cpp +++ b/Kernel/Syscalls/kill.cpp @@ -65,7 +65,7 @@ ErrorOr Process::do_killall(int signal) ErrorOr error; // Send the signal to all processes we have access to for. - processes().for_each([&](auto& process) { + Process::all_instances().for_each([&](auto& process) { ErrorOr res; if (process.pid() == pid()) res = do_killself(signal);