From 2c2398b5498612c9cd880a1e35dff156ba7949d8 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Tue, 14 Feb 2023 20:25:19 -0800 Subject: [PATCH] [kernel] Protect process::m_threads with a lock Another spot I meant to go back and clean up with a lock - found it when a process with threads running on two CPUs exited, and the scheduler tried to delete the process on both CPUs. --- src/kernel/objects/process.cpp | 16 +++++++++++++++- src/kernel/objects/process.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/kernel/objects/process.cpp b/src/kernel/objects/process.cpp index d022f3e..b0bc880 100644 --- a/src/kernel/objects/process.cpp +++ b/src/kernel/objects/process.cpp @@ -52,7 +52,11 @@ process::create_kernel_process(page_table *pml4) void process::exit(int32_t code) { - // TODO: make this thread-safe + util::scoped_lock lock {m_threads_lock}; + + if (m_state == state::exited) + return; + m_state = state::exited; m_return_code = code; @@ -67,6 +71,9 @@ process::exit(int32_t code) void process::update() { + util::scoped_lock lock {m_threads_lock}; + + kassert(false, "process::update used!"); kassert(m_threads.count() > 0, "process::update with zero threads!"); size_t i = 0; @@ -86,6 +93,11 @@ process::update() thread * process::create_thread(uintptr_t rsp3, uint8_t priority) { + util::scoped_lock lock {m_threads_lock}; + + if (m_state == state::exited) + return nullptr; + if (priority == default_priority) priority = scheduler::default_priority; @@ -103,6 +115,8 @@ process::create_thread(uintptr_t rsp3, uint8_t priority) bool process::thread_exited(thread *th) { + util::scoped_lock lock {m_threads_lock}; + kassert(&th->m_parent == this, "Process got thread_exited for non-child!"); m_threads.remove_swap(th); remove_handle(th->self_handle()); diff --git a/src/kernel/objects/process.h b/src/kernel/objects/process.h index e2b2511..fb6614a 100644 --- a/src/kernel/objects/process.h +++ b/src/kernel/objects/process.h @@ -111,6 +111,7 @@ private: vm_space m_space; util::vector m_threads; + util::spinlock m_threads_lock; util::node_set m_handles; util::spinlock m_handles_lock;