Kernel: add Thread::queue_signal()

This commit is contained in:
Bananymous 2023-07-24 22:26:10 +03:00
parent 146802fa4c
commit 522aa8e762
3 changed files with 25 additions and 13 deletions

View File

@ -40,6 +40,7 @@ namespace Kernel
bool has_signal_to_execute() const;
void set_signal_done(int signal);
void handle_next_signal();
void queue_signal(int signal);
void set_return_rsp(uintptr_t& rsp) { m_return_rsp = &rsp; }
void set_return_rip(uintptr_t& rip) { m_return_rip = &rip; }
@ -99,10 +100,9 @@ namespace Kernel
BAN::CircularQueue<int, 10> m_signal_queue;
uint64_t m_signal_mask { 0 };
bool m_handling_signal { false };
int m_handling_signal { 0 };
static_assert(_SIGMAX < 64);
friend class Process;
friend class Scheduler;
};

View File

@ -7,7 +7,6 @@
#include <kernel/Memory/PageTableScope.h>
#include <kernel/Process.h>
#include <kernel/Scheduler.h>
#include <kernel/Signal.h>
#include <LibELF/ELF.h>
#include <LibELF/Values.h>
@ -826,7 +825,7 @@ namespace Kernel
if (process->pid() == pid)
{
if (signal)
process->m_threads.front()->m_signal_queue.push(signal);
process->m_threads.front()->queue_signal(signal);
return 0;
}
}
@ -841,7 +840,7 @@ namespace Kernel
ASSERT(m_threads.size() == 1);
CriticalScope _;
Thread& current = Thread::current();
current.m_signal_queue.push(signal);
current.queue_signal(signal);
current.handle_next_signal();
return 0;
}

View File

@ -152,14 +152,12 @@ namespace Kernel
void Thread::set_signal_done(int signal)
{
ASSERT(!interrupts_enabled());
if (!m_handling_signal)
if (m_handling_signal == 0)
derrorln("set_signal_done called while not handling singal");
else if (m_signal_queue.empty())
derrorln("set_signal_done called and there are no signals in queue");
else if (m_signal_queue.front() != signal)
derrorln("set_signal_done called with wrong signal");
if (m_handling_signal != signal)
derrorln("set_signal_done called with invalid signal");
else
m_signal_queue.pop();
m_handling_signal = 0;
}
void Thread::handle_next_signal()
@ -171,6 +169,7 @@ namespace Kernel
int signal = m_signal_queue.front();
ASSERT(signal >= _SIGMIN && signal <= _SIGMAX);
m_signal_queue.pop();
uintptr_t& return_rsp = this->return_rsp();
uintptr_t& return_rip = this->return_rip();
@ -187,7 +186,7 @@ namespace Kernel
// call userspace signal handlers
// FIXME: signal trampoline should take a hash etc
// to only allow marking signals done from it
m_handling_signal = true;
m_handling_signal = signal;
write_to_stack(return_rsp, return_rip);
write_to_stack(return_rsp, signal);
write_to_stack(return_rsp, signal_handler);
@ -228,6 +227,9 @@ namespace Kernel
case SIGPROF:
case SIGVTALRM:
{
// NOTE: we cannot have schedulers temporary stack when
// enabling interrupts
asm volatile("movq %0, %%rsp" :: "r"(m_return_rsp));
ENABLE_INTERRUPTS();
process().exit(128 + signal);
ASSERT_NOT_REACHED();
@ -249,8 +251,19 @@ namespace Kernel
ASSERT_NOT_REACHED();
}
}
}
m_signal_queue.pop();
void Thread::queue_signal(int signal)
{
ASSERT(!interrupts_enabled());
if (m_signal_queue.full())
{
dwarnln("Signal queue full");
return;
}
m_signal_queue.push(signal);
if (this != &Thread::current())
Scheduler::get().unblock_thread(tid());
}
void Thread::validate_stack() const