From 93975fdc456cb1cce58e1dfbf618b7636359cb0b Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 26 Mar 2024 02:46:51 +0200 Subject: [PATCH] Kernel: Process signal mask is now 2 32 bit values This allows signal mask to be atomic on 32 bit target --- kernel/include/kernel/Process.h | 30 +++++++++++++++++++++++++++++- kernel/include/kernel/Thread.h | 1 + kernel/kernel/Process.cpp | 4 ++-- kernel/kernel/Thread.cpp | 12 +++++++++--- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 1927a23e27..056cc93c11 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -199,6 +199,33 @@ namespace Kernel BAN::ErrorOr validate_string_access(const char*); BAN::ErrorOr validate_pointer_access(const void*, size_t); + uint64_t signal_pending_mask() const + { + return ((uint64_t)m_signal_pending_mask[1].load() << 32) | m_signal_pending_mask[0].load(); + } + + void add_pending_signal(uint8_t signal) + { + ASSERT(signal >= _SIGMIN); + ASSERT(signal <= _SIGMAX); + ASSERT(signal < 64); + if (signal < 32) + m_signal_pending_mask[0] |= (uint32_t)1 << signal; + else + m_signal_pending_mask[1] |= (uint32_t)1 << (signal - 32); + } + + void remove_pending_signal(uint8_t signal) + { + ASSERT(signal >= _SIGMIN); + ASSERT(signal <= _SIGMAX); + ASSERT(signal < 64); + if (signal < 32) + m_signal_pending_mask[0] &= ~((uint32_t)1 << signal); + else + m_signal_pending_mask[1] &= ~((uint32_t)1 << (signal - 32)); + } + private: struct ExitStatus { @@ -226,7 +253,8 @@ namespace Kernel BAN::Vector m_threads; BAN::Atomic m_signal_handlers[_SIGMAX + 1] { }; - BAN::Atomic m_signal_pending_mask { 0 }; + // This is 2 32 bit values to allow atomicity on 32 targets + BAN::Atomic m_signal_pending_mask[2] { 0, 0 }; BAN::Vector m_cmdline; BAN::Vector m_environ; diff --git a/kernel/include/kernel/Thread.h b/kernel/include/kernel/Thread.h index bae255407e..5e66069b20 100644 --- a/kernel/include/kernel/Thread.h +++ b/kernel/include/kernel/Thread.h @@ -79,6 +79,7 @@ namespace Kernel static pid_t current_tid(); Process& process(); + const Process& process() const; bool has_process() const { return m_process; } bool is_userspace() const { return m_is_userspace; } diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 721759bebb..2d757a10c8 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1488,7 +1488,7 @@ namespace Kernel if (pid == m_pid) { - m_signal_pending_mask |= 1 << signal; + add_pending_signal(signal); return 0; } @@ -1501,7 +1501,7 @@ namespace Kernel found = true; if (signal) { - process.m_signal_pending_mask |= 1 << signal; + process.add_pending_signal(signal); // FIXME: This feels hacky Scheduler::get().unblock_thread(process.m_threads.front()->tid()); } diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index 4f61e15487..d757673f78 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -140,6 +140,12 @@ namespace Kernel return *m_process; } + const Process& Thread::process() const + { + ASSERT(m_process); + return *m_process; + } + Thread::~Thread() { } @@ -241,7 +247,7 @@ namespace Kernel auto& interrupt_stack = *reinterpret_cast(interrupt_stack_base() + interrupt_stack_size() - sizeof(InterruptStack)); if (!GDT::is_user_segment(interrupt_stack.cs)) return false; - uint64_t full_pending_mask = m_signal_pending_mask | m_process->m_signal_pending_mask; + uint64_t full_pending_mask = m_signal_pending_mask | process().signal_pending_mask();; return full_pending_mask & ~m_signal_block_mask; } @@ -265,7 +271,7 @@ namespace Kernel if (signal == 0) { - uint64_t full_pending_mask = m_signal_pending_mask | process().m_signal_pending_mask; + uint64_t full_pending_mask = m_signal_pending_mask | process().signal_pending_mask(); for (signal = _SIGMIN; signal <= _SIGMAX; signal++) { uint64_t mask = 1ull << signal; @@ -283,7 +289,7 @@ namespace Kernel vaddr_t signal_handler = process().m_signal_handlers[signal]; m_signal_pending_mask &= ~(1ull << signal); - process().m_signal_pending_mask &= ~(1ull << signal); + process().remove_pending_signal(signal); if (signal_handler == (vaddr_t)SIG_IGN) ;