Kernel: Generally improve signals

This commit is contained in:
Bananymous 2023-07-31 22:28:18 +03:00
parent 8ec6d4c9fc
commit e86e755c51
6 changed files with 46 additions and 19 deletions

View File

@ -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()

View File

@ -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;
}; };

View File

@ -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)

View File

@ -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:

View File

@ -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();

View File

@ -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
{ {