libluna+kernel: Add Bitset and use it for signals
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
d144a818d8
commit
a35ca0b367
@ -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;
|
if (push_mem_on_stack((u8*)&handler.__sa_sigreturn, sizeof(void*)).has_error()) return false;
|
||||||
|
|
||||||
signal_mask = handler.sa_mask;
|
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;
|
rsp = regs.rsp;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ Result<void> ConsoleDevice::handle_background_process_group(bool can_succeed, in
|
|||||||
auto* current = Scheduler::current();
|
auto* current = Scheduler::current();
|
||||||
if (current->pgid == foreground_pgrp) return {};
|
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 {};
|
if (can_succeed) return {};
|
||||||
return err(EIO);
|
return err(EIO);
|
||||||
|
@ -79,7 +79,8 @@ Result<u64> sys_sigprocmask(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
if (oldset)
|
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)
|
if (set)
|
||||||
@ -89,8 +90,8 @@ Result<u64> sys_sigprocmask(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
switch (how)
|
switch (how)
|
||||||
{
|
{
|
||||||
case SIG_BLOCK: current->signal_mask |= kset; break;
|
case SIG_BLOCK: current->signal_mask = current->signal_mask.value() | kset; break;
|
||||||
case SIG_UNBLOCK: current->signal_mask &= ~kset; break;
|
case SIG_UNBLOCK: current->signal_mask = current->signal_mask.value() & ~kset; break;
|
||||||
case SIG_SETMASK: current->signal_mask = kset; break;
|
case SIG_SETMASK: current->signal_mask = kset; break;
|
||||||
default: return err(EINVAL);
|
default: return err(EINVAL);
|
||||||
}
|
}
|
||||||
|
@ -148,10 +148,10 @@ void Thread::process_pending_signals(Registers* current_regs)
|
|||||||
for (int i = 0; i < NSIG; i++)
|
for (int i = 0; i < NSIG; i++)
|
||||||
{
|
{
|
||||||
int signo = i + 1;
|
int signo = i + 1;
|
||||||
if (signo != SIGKILL && signo != SIGSTOP && signal_mask & (1 << i)) continue;
|
if (signo != SIGKILL && signo != SIGSTOP && signal_mask.get(i)) continue;
|
||||||
if (pending_signals & (1 << i))
|
if (pending_signals.get(i))
|
||||||
{
|
{
|
||||||
pending_signals &= ~(1 << i);
|
pending_signals.set(i, false);
|
||||||
kinfoln("signal: executing signal %d for thread %d", signo, id);
|
kinfoln("signal: executing signal %d for thread %d", signo, id);
|
||||||
auto handler = signal_handlers[i];
|
auto handler = signal_handlers[i];
|
||||||
if (signo != SIGKILL && signo != SIGSTOP && handler.sa_handler == SIG_IGN)
|
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++)
|
for (int i = 0; i < NSIG; i++)
|
||||||
{
|
{
|
||||||
if (pending_signals & (1 << i))
|
if (pending_signals.get(i))
|
||||||
{
|
{
|
||||||
int signo = i + 1;
|
int signo = i + 1;
|
||||||
if (signo == SIGKILL || signo == SIGSTOP) return false;
|
if (signo == SIGKILL || signo == SIGSTOP) return false;
|
||||||
if (signal_mask & (1 << i)) continue;
|
if (signal_mask.get(i)) continue;
|
||||||
auto handler = signal_handlers[i];
|
auto handler = signal_handlers[i];
|
||||||
if (handler.sa_handler == SIG_IGN) return true;
|
if (handler.sa_handler == SIG_IGN) return true;
|
||||||
if (handler.sa_handler == SIG_DFL && default_actions[i] == DefaultSignalAction::Ignore) 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;
|
if (is_kernel) return;
|
||||||
|
|
||||||
check(signo > 0 && signo <= NSIG);
|
check(signo > 0 && signo <= NSIG);
|
||||||
pending_signals |= 1 << (signo - 1);
|
pending_signals.set(signo - 1, true);
|
||||||
|
|
||||||
if (state == ThreadState::Waiting || state == ThreadState::Sleeping)
|
if (state == ThreadState::Waiting || state == ThreadState::Sleeping)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "fs/VFS.h"
|
#include "fs/VFS.h"
|
||||||
#include "memory/AddressSpace.h"
|
#include "memory/AddressSpace.h"
|
||||||
#include <bits/signal.h>
|
#include <bits/signal.h>
|
||||||
|
#include <luna/Bitset.h>
|
||||||
#include <luna/LinkedList.h>
|
#include <luna/LinkedList.h>
|
||||||
#include <luna/OwnedPtr.h>
|
#include <luna/OwnedPtr.h>
|
||||||
#include <luna/Result.h>
|
#include <luna/Result.h>
|
||||||
@ -105,8 +106,8 @@ struct Thread : public LinkedListNode<Thread>
|
|||||||
SharedPtr<VFS::Inode>* parent_inode = nullptr);
|
SharedPtr<VFS::Inode>* parent_inode = nullptr);
|
||||||
|
|
||||||
struct sigaction signal_handlers[NSIG];
|
struct sigaction signal_handlers[NSIG];
|
||||||
sigset_t signal_mask { 0 };
|
Bitset<sigset_t> signal_mask { 0 };
|
||||||
sigset_t pending_signals { 0 };
|
Bitset<sigset_t> pending_signals { 0 };
|
||||||
bool interrupted { false };
|
bool interrupted { false };
|
||||||
|
|
||||||
bool unrestricted_task { false };
|
bool unrestricted_task { false };
|
||||||
|
58
libluna/include/luna/Bitset.h
Normal file
58
libluna/include/luna/Bitset.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <luna/Check.h>
|
||||||
|
|
||||||
|
template <typename T> class Bitset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Bitset() : m_value()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitset(T value) : m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitset(const Bitset<T>& other) : m_value(other.m_value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitset<T>& operator=(T value)
|
||||||
|
{
|
||||||
|
m_value = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitset<T>& operator=(const Bitset<T>& 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;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user