forked from Bananymous/banan-os
Kernel: add Thread::queue_signal()
This commit is contained in:
parent
146802fa4c
commit
522aa8e762
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue