Kernel: Cleanup returns from any kind on interrupts

This commit is contained in:
Bananymous 2023-08-01 14:23:50 +03:00
parent 13852e865c
commit 217dbca7b7
6 changed files with 57 additions and 71 deletions

View File

@ -138,7 +138,10 @@ namespace IDT
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs)
{
Kernel::Thread::current().save_sse();
bool from_userspace = (interrupt_stack.cs & 0b11) == 0b11;
if (from_userspace)
Kernel::Thread::current().save_sse();
pid_t tid = Kernel::Scheduler::current_tid();
pid_t pid = tid ? Kernel::Process::current().pid() : 0;
@ -198,22 +201,23 @@ namespace IDT
Kernel::panic("Unhandled exception");
}
switch (Kernel::Thread::current().state())
{
case Kernel::Thread::State::Terminating:
ASSERT_NOT_REACHED();
case Kernel::Thread::State::Terminated:
// Don't continue exection when terminated
if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated)
Kernel::Scheduler::get().execute_current_thread();
default:
break;
if (from_userspace)
{
ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating);
Kernel::Thread::current().load_sse();
}
Kernel::Thread::current().load_sse();
}
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
{
Kernel::Thread::current().save_sse();
bool from_userspace = (interrupt_stack.cs & 0b11) & 0b11;
if (from_userspace)
Kernel::Thread::current().save_sse();
if (Kernel::Scheduler::current_tid())
{
@ -239,17 +243,15 @@ namespace IDT
Kernel::Scheduler::get().reschedule_if_idling();
switch (Kernel::Thread::current().state())
{
case Kernel::Thread::State::Terminating:
ASSERT_NOT_REACHED();
case Kernel::Thread::State::Terminated:
// Don't continue exection when terminated
if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated)
Kernel::Scheduler::get().execute_current_thread();
default:
break;
}
Kernel::Thread::current().load_sse();
if (from_userspace)
{
ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating);
Kernel::Thread::current().load_sse();
}
}
static void flush_idt()

View File

@ -43,7 +43,7 @@ namespace Kernel
~Process();
void cleanup_function();
void exit(int status);
void exit(int status, int signal);
void add_thread(Thread*);
void on_thread_exit(Thread&);

View File

@ -116,7 +116,6 @@ namespace Kernel
alignas(16) uint8_t m_sse_storage[512];
friend class TerminateBlocker;
friend class Scheduler;
};

View File

@ -14,6 +14,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <sys/sysmacros.h>
#include <sys/wait.h>
namespace Kernel
{
@ -178,17 +179,17 @@ namespace Kernel
ASSERT_NOT_REACHED();
}
void Process::exit(int status)
void Process::exit(int status, int signal)
{
LockGuard _(m_lock);
m_exit_status.exit_code = status;
m_exit_status.exit_code = __WGENEXITCODE(status, signal);
for (auto* thread : m_threads)
thread->set_terminating();
}
BAN::ErrorOr<long> Process::sys_exit(int status)
{
exit(status);
exit(status, 0);
Thread::TerminateBlocker _(Thread::current());
ASSERT_NOT_REACHED();
}
@ -427,11 +428,8 @@ namespace Kernel
int Process::block_until_exit()
{
ASSERT(s_process_lock.is_locked());
ASSERT(this != &Process::current());
s_process_lock.unlock();
m_lock.lock();
m_exit_status.waiting++;
while (!m_exit_status.exited)
@ -445,8 +443,6 @@ namespace Kernel
m_exit_status.waiting--;
m_lock.unlock();
s_process_lock.lock();
return ret;
}
@ -458,10 +454,12 @@ namespace Kernel
if (options)
return BAN::Error::from_errno(EINVAL);
LockGuard _(s_process_lock);
for (auto* process : s_processes)
if (process->pid() == pid)
target = process;
{
LockGuard _(s_process_lock);
for (auto* process : s_processes)
if (process->pid() == pid)
target = process;
}
if (target == nullptr)
return BAN::Error::from_errno(ECHILD);
@ -580,7 +578,6 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_read(int fd, void* buffer, size_t count)
{
Thread::TerminateBlocker blocker(Thread::current());
LockGuard _(m_lock);
return TRY(m_open_file_descriptors.read(fd, buffer, count));
}

View File

@ -21,6 +21,8 @@ namespace Kernel
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack& interrupt_stack)
{
ASSERT((interrupt_stack.cs & 0b11) == 0b11);
Thread::current().set_return_rsp(interrupt_stack.rsp);
Thread::current().set_return_rip(interrupt_stack.rip);
@ -175,16 +177,11 @@ 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;
}
// Don't continue exection when terminated
if (Kernel::Thread::current().state() == Kernel::Thread::State::Terminated)
Kernel::Scheduler::get().execute_current_thread();
ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating);
Thread::current().load_sse();
if (ret.is_error())

View File

@ -29,36 +29,32 @@ namespace Kernel
Thread::TerminateBlocker::TerminateBlocker(Thread& thread)
: m_thread(thread)
{
CriticalScope _;
if (m_thread.state() == State::Executing || m_thread.m_terminate_blockers > 0)
{
CriticalScope _;
if (m_thread.state() == State::Executing || m_thread.m_terminate_blockers > 0)
{
m_thread.m_terminate_blockers++;
return;
}
if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0)
m_thread.m_state = State::Terminated;
m_thread.m_terminate_blockers++;
return;
}
if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0)
m_thread.m_state = State::Terminated;
while (true)
Scheduler::get().reschedule();
}
Thread::TerminateBlocker::~TerminateBlocker()
{
{
CriticalScope _;
m_thread.m_terminate_blockers--;
CriticalScope _;
if (m_thread.state() == State::Executing || m_thread.m_terminate_blockers > 0)
return;
m_thread.m_terminate_blockers--;
if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0)
m_thread.m_state = State::Terminated;
}
if (m_thread.state() == State::Executing || m_thread.m_terminate_blockers > 0)
return;
if (m_thread.state() == State::Terminating && m_thread.m_terminate_blockers == 0)
m_thread.m_state = State::Terminated;
while (true)
Scheduler::get().reschedule();
@ -299,11 +295,8 @@ namespace Kernel
case SIGTRAP:
case SIGXCPU:
case SIGXFSZ:
{
auto message = BAN::String::formatted("killed by signal {}\n", signal);
(void)process().tty().write(0, message.data(), message.size());
}
// fall through
process().exit(128 + signal, signal | 0x80);
break;
// Abnormal termination of the process
case SIGALRM:
@ -317,10 +310,8 @@ namespace Kernel
case SIGPOLL:
case SIGPROF:
case SIGVTALRM:
{
process().exit(128 + signal);
process().exit(128 + signal, signal);
break;
}
// Ignore the signal
case SIGCHLD: