diff --git a/kernel/src/arch/x86_64/Thread.cpp b/kernel/src/arch/x86_64/Thread.cpp index 10f2e79d..5474913b 100644 --- a/kernel/src/arch/x86_64/Thread.cpp +++ b/kernel/src/arch/x86_64/Thread.cpp @@ -124,7 +124,7 @@ bool Thread::deliver_signal(int signo, Registers* current_regs) if (push_mem_on_stack((u8*)&handler.__sa_sigreturn, sizeof(void*)).has_error()) return false; signal_mask = handler.sa_mask; - if ((handler.sa_flags & SA_NODEFER) == 0) signal_mask |= (1 << (signo - 1)); + if ((handler.sa_flags & SA_NODEFER) == 0) signal_mask.set(signo - 1, true); rsp = regs.rsp; diff --git a/kernel/src/fs/devices/ConsoleDevice.cpp b/kernel/src/fs/devices/ConsoleDevice.cpp index de11aa67..c592e0a8 100644 --- a/kernel/src/fs/devices/ConsoleDevice.cpp +++ b/kernel/src/fs/devices/ConsoleDevice.cpp @@ -36,7 +36,7 @@ Result ConsoleDevice::handle_background_process_group(bool can_succeed, in auto* current = Scheduler::current(); if (current->pgid == foreground_pgrp) return {}; - if ((current->signal_mask & (1 << (signo - 1))) || (current->signal_handlers[signo - 1].sa_handler == SIG_IGN)) + if ((current->signal_mask.get(signo - 1)) || (current->signal_handlers[signo - 1].sa_handler == SIG_IGN)) { if (can_succeed) return {}; return err(EIO); diff --git a/kernel/src/sys/signal.cpp b/kernel/src/sys/signal.cpp index 8e3f139d..779b151c 100644 --- a/kernel/src/sys/signal.cpp +++ b/kernel/src/sys/signal.cpp @@ -79,7 +79,8 @@ Result sys_sigprocmask(Registers*, SyscallArgs args) if (oldset) { - if (!MemoryManager::copy_to_user_typed(oldset, ¤t->signal_mask)) return err(EFAULT); + sigset_t mask = current->signal_mask.value(); + if (!MemoryManager::copy_to_user_typed(oldset, &mask)) return err(EFAULT); } if (set) @@ -89,8 +90,8 @@ Result sys_sigprocmask(Registers*, SyscallArgs args) switch (how) { - case SIG_BLOCK: current->signal_mask |= kset; break; - case SIG_UNBLOCK: current->signal_mask &= ~kset; break; + case SIG_BLOCK: current->signal_mask = current->signal_mask.value() | kset; break; + case SIG_UNBLOCK: current->signal_mask = current->signal_mask.value() & ~kset; break; case SIG_SETMASK: current->signal_mask = kset; break; default: return err(EINVAL); } diff --git a/kernel/src/thread/Thread.cpp b/kernel/src/thread/Thread.cpp index 6c8e0806..8907c917 100644 --- a/kernel/src/thread/Thread.cpp +++ b/kernel/src/thread/Thread.cpp @@ -148,10 +148,10 @@ void Thread::process_pending_signals(Registers* current_regs) for (int i = 0; i < NSIG; i++) { int signo = i + 1; - if (signo != SIGKILL && signo != SIGSTOP && signal_mask & (1 << i)) continue; - if (pending_signals & (1 << i)) + if (signo != SIGKILL && signo != SIGSTOP && signal_mask.get(i)) continue; + if (pending_signals.get(i)) { - pending_signals &= ~(1 << i); + pending_signals.set(i, false); kinfoln("signal: executing signal %d for thread %d", signo, id); auto handler = signal_handlers[i]; if (signo != SIGKILL && signo != SIGSTOP && handler.sa_handler == SIG_IGN) @@ -190,11 +190,11 @@ bool Thread::will_ignore_pending_signal() { for (int i = 0; i < NSIG; i++) { - if (pending_signals & (1 << i)) + if (pending_signals.get(i)) { int signo = i + 1; if (signo == SIGKILL || signo == SIGSTOP) return false; - if (signal_mask & (1 << i)) continue; + if (signal_mask.get(i)) continue; auto handler = signal_handlers[i]; if (handler.sa_handler == SIG_IGN) return true; if (handler.sa_handler == SIG_DFL && default_actions[i] == DefaultSignalAction::Ignore) return true; @@ -209,7 +209,7 @@ void Thread::send_signal(int signo) if (is_kernel) return; check(signo > 0 && signo <= NSIG); - pending_signals |= 1 << (signo - 1); + pending_signals.set(signo - 1, true); if (state == ThreadState::Waiting || state == ThreadState::Sleeping) { diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index 585f02b2..0f7d4327 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -4,6 +4,7 @@ #include "fs/VFS.h" #include "memory/AddressSpace.h" #include +#include #include #include #include @@ -105,8 +106,8 @@ struct Thread : public LinkedListNode SharedPtr* parent_inode = nullptr); struct sigaction signal_handlers[NSIG]; - sigset_t signal_mask { 0 }; - sigset_t pending_signals { 0 }; + Bitset signal_mask { 0 }; + Bitset pending_signals { 0 }; bool interrupted { false }; bool unrestricted_task { false }; diff --git a/libluna/include/luna/Bitset.h b/libluna/include/luna/Bitset.h new file mode 100644 index 00000000..a2755cfb --- /dev/null +++ b/libluna/include/luna/Bitset.h @@ -0,0 +1,58 @@ +#pragma once +#include + +template class Bitset +{ + public: + Bitset() : m_value() + { + } + + Bitset(T value) : m_value(value) + { + } + + Bitset(const Bitset& other) : m_value(other.m_value) + { + } + + Bitset& operator=(T value) + { + m_value = value; + return *this; + } + + Bitset& operator=(const Bitset& other) + { + if (&other == this) return *this; + m_value = other.m_value; + return *this; + } + + T value() const + { + return m_value; + } + + void set(int index, bool b) + { + check((usize)index < (sizeof(T) * 8)); + if (b) m_value |= (((T)1) << index); + else + m_value &= ~(((T)1) << index); + } + + bool get(int index) + { + check((usize)index < (sizeof(T) * 8)); + return m_value & (((T)1) << index); + } + + void clear() + { + m_value = 0; + } + + private: + T m_value; +};