forked from Bananymous/banan-os
Kernel: Cleanup returns from any kind on interrupts
This commit is contained in:
parent
13852e865c
commit
217dbca7b7
|
@ -138,6 +138,9 @@ namespace IDT
|
|||
|
||||
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs)
|
||||
{
|
||||
bool from_userspace = (interrupt_stack.cs & 0b11) == 0b11;
|
||||
|
||||
if (from_userspace)
|
||||
Kernel::Thread::current().save_sse();
|
||||
|
||||
pid_t tid = Kernel::Scheduler::current_tid();
|
||||
|
@ -198,21 +201,22 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
|
||||
{
|
||||
bool from_userspace = (interrupt_stack.cs & 0b11) & 0b11;
|
||||
|
||||
if (from_userspace)
|
||||
Kernel::Thread::current().save_sse();
|
||||
|
||||
if (Kernel::Scheduler::current_tid())
|
||||
|
@ -239,18 +243,16 @@ 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;
|
||||
}
|
||||
|
||||
if (from_userspace)
|
||||
{
|
||||
ASSERT(Kernel::Thread::current().state() != Kernel::Thread::State::Terminating);
|
||||
Kernel::Thread::current().load_sse();
|
||||
}
|
||||
}
|
||||
|
||||
static void flush_idt()
|
||||
{
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -116,7 +116,6 @@ namespace Kernel
|
|||
|
||||
alignas(16) uint8_t m_sse_storage[512];
|
||||
|
||||
friend class TerminateBlocker;
|
||||
friend class Scheduler;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -28,7 +28,6 @@ namespace Kernel
|
|||
|
||||
Thread::TerminateBlocker::TerminateBlocker(Thread& thread)
|
||||
: m_thread(thread)
|
||||
{
|
||||
{
|
||||
CriticalScope _;
|
||||
|
||||
|
@ -40,14 +39,12 @@ namespace Kernel
|
|||
|
||||
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 _;
|
||||
|
||||
|
@ -58,7 +55,6 @@ namespace Kernel
|
|||
|
||||
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:
|
||||
|
|
Loading…
Reference in New Issue