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

View File

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

View File

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