forked from Bananymous/banan-os
Kernel: Generally improve signals
This commit is contained in:
parent
8ec6d4c9fc
commit
e86e755c51
|
@ -189,12 +189,22 @@ namespace IDT
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::Thread::current().handle_signal(-signal);
|
Kernel::Thread::current().handle_signal(signal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Kernel::panic("Unhandled exception");
|
Kernel::panic("Unhandled exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (Kernel::Thread::current().state())
|
||||||
|
{
|
||||||
|
case Kernel::Thread::State::Terminating:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
case Kernel::Thread::State::Terminated:
|
||||||
|
Kernel::Scheduler::get().execute_current_thread();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
|
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
|
||||||
|
@ -222,6 +232,16 @@ namespace IDT
|
||||||
InterruptController::get().eoi(irq);
|
InterruptController::get().eoi(irq);
|
||||||
|
|
||||||
Kernel::Scheduler::get().reschedule_if_idling();
|
Kernel::Scheduler::get().reschedule_if_idling();
|
||||||
|
|
||||||
|
switch (Kernel::Thread::current().state())
|
||||||
|
{
|
||||||
|
case Kernel::Thread::State::Terminating:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
case Kernel::Thread::State::Terminated:
|
||||||
|
Kernel::Scheduler::get().execute_current_thread();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_idt()
|
static void flush_idt()
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace Kernel
|
||||||
|
|
||||||
static bool is_valid_tid(pid_t tid);
|
static bool is_valid_tid(pid_t tid);
|
||||||
|
|
||||||
|
[[noreturn]] void execute_current_thread();
|
||||||
[[noreturn]] void delete_current_process_and_thread();
|
[[noreturn]] void delete_current_process_and_thread();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -39,7 +40,6 @@ namespace Kernel
|
||||||
[[nodiscard]] bool save_current_thread();
|
[[nodiscard]] bool save_current_thread();
|
||||||
void remove_and_advance_current_thread();
|
void remove_and_advance_current_thread();
|
||||||
void advance_current_thread();
|
void advance_current_thread();
|
||||||
[[noreturn]] void execute_current_thread();
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> add_thread(Thread*);
|
BAN::ErrorOr<void> add_thread(Thread*);
|
||||||
|
|
||||||
|
@ -75,7 +75,6 @@ namespace Kernel
|
||||||
|
|
||||||
uint64_t m_last_reschedule = 0;
|
uint64_t m_last_reschedule = 0;
|
||||||
|
|
||||||
friend class Thread;
|
|
||||||
friend class Process;
|
friend class Process;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -418,9 +418,9 @@ namespace Kernel
|
||||||
m_userspace_info.argc = str_argv.size();
|
m_userspace_info.argc = str_argv.size();
|
||||||
|
|
||||||
asm volatile("cli");
|
asm volatile("cli");
|
||||||
m_threads.front()->setup_exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_threads.front()->setup_exec();
|
||||||
Scheduler::get().execute_current_thread();
|
Scheduler::get().execute_current_thread();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -867,8 +867,8 @@ namespace Kernel
|
||||||
ASSERT(this == &Process::current());
|
ASSERT(this == &Process::current());
|
||||||
|
|
||||||
CriticalScope _;
|
CriticalScope _;
|
||||||
Thread::current().handle_signal(-signal);
|
Thread::current().handle_signal(signal);
|
||||||
ASSERT_NOT_REACHED();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_tcsetpgrp(int fd, pid_t pgid)
|
BAN::ErrorOr<long> Process::sys_tcsetpgrp(int fd, pid_t pgid)
|
||||||
|
|
|
@ -86,7 +86,6 @@ namespace Kernel
|
||||||
|
|
||||||
void Scheduler::reschedule()
|
void Scheduler::reschedule()
|
||||||
{
|
{
|
||||||
VERIFY_STI();
|
|
||||||
DISABLE_INTERRUPTS();
|
DISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if (save_current_thread())
|
if (save_current_thread())
|
||||||
|
@ -247,7 +246,7 @@ namespace Kernel
|
||||||
current->set_started();
|
current->set_started();
|
||||||
start_thread(current->rsp(), current->rip());
|
start_thread(current->rsp(), current->rip());
|
||||||
case Thread::State::Executing:
|
case Thread::State::Executing:
|
||||||
while (current->has_signal_to_execute() && current->state() == Thread::State::Executing)
|
while (current->has_signal_to_execute())
|
||||||
current->handle_signal();
|
current->handle_signal();
|
||||||
// fall through
|
// fall through
|
||||||
case Thread::State::Terminating:
|
case Thread::State::Terminating:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <kernel/Debug.h>
|
#include <kernel/Debug.h>
|
||||||
#include <kernel/InterruptStack.h>
|
#include <kernel/InterruptStack.h>
|
||||||
#include <kernel/Process.h>
|
#include <kernel/Process.h>
|
||||||
|
#include <kernel/Scheduler.h>
|
||||||
#include <kernel/Syscall.h>
|
#include <kernel/Syscall.h>
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
@ -172,6 +173,16 @@ namespace Kernel
|
||||||
|
|
||||||
asm volatile("cli");
|
asm volatile("cli");
|
||||||
|
|
||||||
|
switch (Thread::current().state())
|
||||||
|
{
|
||||||
|
case Thread::State::Terminating:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
case Thread::State::Terminated:
|
||||||
|
Scheduler::get().execute_current_thread();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret.is_error())
|
if (ret.is_error())
|
||||||
return -ret.error().get_error_code();
|
return -ret.error().get_error_code();
|
||||||
return ret.value();
|
return ret.value();
|
||||||
|
|
|
@ -218,7 +218,7 @@ namespace Kernel
|
||||||
|
|
||||||
bool Thread::has_signal_to_execute() const
|
bool Thread::has_signal_to_execute() const
|
||||||
{
|
{
|
||||||
if (!m_process || m_handling_signal)
|
if (!is_userspace() || m_handling_signal || m_state != State::Executing)
|
||||||
return false;
|
return false;
|
||||||
uint64_t full_pending_mask = m_signal_pending_mask | m_process->m_signal_pending_mask;
|
uint64_t full_pending_mask = m_signal_pending_mask | m_process->m_signal_pending_mask;
|
||||||
return full_pending_mask & ~m_signal_block_mask;
|
return full_pending_mask & ~m_signal_block_mask;
|
||||||
|
@ -229,10 +229,14 @@ namespace Kernel
|
||||||
ASSERT(!interrupts_enabled());
|
ASSERT(!interrupts_enabled());
|
||||||
if (m_handling_signal == 0)
|
if (m_handling_signal == 0)
|
||||||
derrorln("set_signal_done called while not handling singal");
|
derrorln("set_signal_done called while not handling singal");
|
||||||
if (m_handling_signal != signal)
|
else if (m_handling_signal != signal)
|
||||||
derrorln("set_signal_done called with invalid signal");
|
derrorln("set_signal_done called with invalid signal");
|
||||||
else
|
else
|
||||||
m_handling_signal = 0;
|
m_handling_signal = 0;
|
||||||
|
|
||||||
|
if (m_handling_signal == 0)
|
||||||
|
while (has_signal_to_execute())
|
||||||
|
handle_signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::handle_signal(int signal)
|
void Thread::handle_signal(int signal)
|
||||||
|
@ -240,6 +244,7 @@ namespace Kernel
|
||||||
ASSERT(!interrupts_enabled());
|
ASSERT(!interrupts_enabled());
|
||||||
ASSERT(&Thread::current() == this);
|
ASSERT(&Thread::current() == this);
|
||||||
ASSERT(is_userspace());
|
ASSERT(is_userspace());
|
||||||
|
ASSERT(!m_handling_signal);
|
||||||
|
|
||||||
if (signal == 0)
|
if (signal == 0)
|
||||||
{
|
{
|
||||||
|
@ -252,16 +257,10 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
ASSERT(signal <= _SIGMAX);
|
ASSERT(signal <= _SIGMAX);
|
||||||
}
|
}
|
||||||
else if (signal > 0)
|
|
||||||
{
|
|
||||||
uint64_t full_pending_mask = m_signal_pending_mask | process().m_signal_pending_mask;
|
|
||||||
uint64_t mask = 1ull << signal;
|
|
||||||
ASSERT(full_pending_mask & mask);
|
|
||||||
ASSERT(!(m_signal_block_mask & mask));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
signal = -signal;
|
ASSERT(signal >= _SIGMIN);
|
||||||
|
ASSERT(signal <= _SIGMAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t& return_rsp = this->return_rsp();
|
uintptr_t& return_rsp = this->return_rsp();
|
||||||
|
@ -284,7 +283,6 @@ namespace Kernel
|
||||||
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);
|
||||||
return_rip = (uintptr_t)signal_trampoline;
|
return_rip = (uintptr_t)signal_trampoline;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue