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;
}
Kernel::Thread::current().handle_signal(-signal);
Kernel::Thread::current().handle_signal(signal);
}
else
{
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)
@ -222,6 +232,16 @@ namespace IDT
InterruptController::get().eoi(irq);
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()

View File

@ -30,6 +30,7 @@ namespace Kernel
static bool is_valid_tid(pid_t tid);
[[noreturn]] void execute_current_thread();
[[noreturn]] void delete_current_process_and_thread();
private:
@ -39,7 +40,6 @@ namespace Kernel
[[nodiscard]] bool save_current_thread();
void remove_and_advance_current_thread();
void advance_current_thread();
[[noreturn]] void execute_current_thread();
BAN::ErrorOr<void> add_thread(Thread*);
@ -75,7 +75,6 @@ namespace Kernel
uint64_t m_last_reschedule = 0;
friend class Thread;
friend class Process;
};

View File

@ -418,9 +418,9 @@ namespace Kernel
m_userspace_info.argc = str_argv.size();
asm volatile("cli");
m_threads.front()->setup_exec();
}
m_threads.front()->setup_exec();
Scheduler::get().execute_current_thread();
ASSERT_NOT_REACHED();
}
@ -867,8 +867,8 @@ namespace Kernel
ASSERT(this == &Process::current());
CriticalScope _;
Thread::current().handle_signal(-signal);
ASSERT_NOT_REACHED();
Thread::current().handle_signal(signal);
return 0;
}
BAN::ErrorOr<long> Process::sys_tcsetpgrp(int fd, pid_t pgid)

View File

@ -86,7 +86,6 @@ namespace Kernel
void Scheduler::reschedule()
{
VERIFY_STI();
DISABLE_INTERRUPTS();
if (save_current_thread())
@ -247,7 +246,7 @@ namespace Kernel
current->set_started();
start_thread(current->rsp(), current->rip());
case Thread::State::Executing:
while (current->has_signal_to_execute() && current->state() == Thread::State::Executing)
while (current->has_signal_to_execute())
current->handle_signal();
// fall through
case Thread::State::Terminating:

View File

@ -1,6 +1,7 @@
#include <kernel/Debug.h>
#include <kernel/InterruptStack.h>
#include <kernel/Process.h>
#include <kernel/Scheduler.h>
#include <kernel/Syscall.h>
#include <termios.h>
@ -172,6 +173,16 @@ namespace Kernel
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())
return -ret.error().get_error_code();
return ret.value();

View File

@ -218,7 +218,7 @@ namespace Kernel
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;
uint64_t full_pending_mask = m_signal_pending_mask | m_process->m_signal_pending_mask;
return full_pending_mask & ~m_signal_block_mask;
@ -229,10 +229,14 @@ namespace Kernel
ASSERT(!interrupts_enabled());
if (m_handling_signal == 0)
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");
else
m_handling_signal = 0;
if (m_handling_signal == 0)
while (has_signal_to_execute())
handle_signal();
}
void Thread::handle_signal(int signal)
@ -240,6 +244,7 @@ namespace Kernel
ASSERT(!interrupts_enabled());
ASSERT(&Thread::current() == this);
ASSERT(is_userspace());
ASSERT(!m_handling_signal);
if (signal == 0)
{
@ -252,16 +257,10 @@ namespace Kernel
}
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
{
signal = -signal;
ASSERT(signal >= _SIGMIN);
ASSERT(signal <= _SIGMAX);
}
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_handler);
return_rip = (uintptr_t)signal_trampoline;
return;
}
else
{