Kernel: Threads can now be terminated mid execution

This commit is contained in:
Bananymous 2023-04-09 22:18:12 +03:00
parent 32359df939
commit e704968f96
6 changed files with 48 additions and 19 deletions

View File

@ -15,7 +15,6 @@ start_thread:
movl 8(%esp), %ecx
movl 4(%esp), %esp
movl $0, %ebp
movl $0, (%esp)
pushl $exit_thread_trampoline
sti
jmp *%ecx

View File

@ -14,7 +14,6 @@ start_thread:
movq %rdi, %rsp
popq %rdi
movq $0, %rbp
movq $0, (%rsp)
pushq $exit_thread_trampoline
sti
jmp *%rsi

View File

@ -23,9 +23,11 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::RefPtr<Process>> create_kernel(entry_t, void*);
~Process() {}
~Process();
BAN::ErrorOr<void> add_thread(entry_t, void*);
void exit();
BAN::ErrorOr<Thread*> add_thread(entry_t, void*);
void on_thread_exit(Thread&);
BAN::ErrorOr<void> init_stdio();

View File

@ -18,6 +18,13 @@ namespace Kernel
public:
using entry_t = void(*)(void*);
enum class State
{
NotStarted,
Executing,
Terminating,
};
public:
static BAN::ErrorOr<Thread*> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr);
~Thread();
@ -29,8 +36,9 @@ namespace Kernel
uintptr_t rsp() const { return m_rsp; }
uintptr_t rip() const { return m_rip; }
void set_started() { m_started = true; }
bool started() const { return m_started; }
void set_started() { ASSERT(m_state == State::NotStarted); m_state = State::Executing; }
State state() const { return m_state; }
void terminate() { m_state = State::Terminating; }
static Thread& current() ;
BAN::RefPtr<Process> process();
@ -46,8 +54,10 @@ namespace Kernel
uintptr_t m_rip = 0;
uintptr_t m_rsp = 0;
const pid_t m_tid = 0;
bool m_started = false;
State m_state { State::NotStarted };
BAN::RefPtr<Process> m_process;
friend class Scheduler;
};
}

View File

@ -23,7 +23,12 @@ namespace Kernel
, m_tty(TTY::current())
{ }
BAN::ErrorOr<void> Process::add_thread(entry_t entry, void* data)
Process::~Process()
{
exit();
}
BAN::ErrorOr<Thread*> Process::add_thread(entry_t entry, void* data)
{
Thread* thread = TRY(Thread::create(entry, data, this));
@ -32,10 +37,10 @@ namespace Kernel
if (auto res = Scheduler::get().add_thread(thread); res.is_error())
{
m_threads.pop_back();
return res;
return res.release_error();
}
return {};
return thread;
}
void Process::on_thread_exit(Thread& thread)
@ -46,6 +51,17 @@ namespace Kernel
m_threads.remove(i);
}
void Process::exit()
{
LockGuard _(m_lock);
for (auto* thread : m_threads)
thread->terminate();
while (!m_threads.empty())
PIT::sleep(1);
for (auto& open_fd : m_open_files)
open_fd.inode = nullptr;
}
BAN::ErrorOr<void> Process::init_stdio()
{
if (!m_open_files.empty())

View File

@ -16,8 +16,8 @@
namespace Kernel
{
extern "C" void start_thread(uintptr_t rsp, uintptr_t rip);
extern "C" void continue_thread(uintptr_t rsp, uintptr_t rip);
extern "C" [[noreturn]] void start_thread(uintptr_t rsp, uintptr_t rip);
extern "C" [[noreturn]] void continue_thread(uintptr_t rsp, uintptr_t rip);
extern "C" uintptr_t read_rip();
static Scheduler* s_instance = nullptr;
@ -166,14 +166,17 @@ namespace Kernel
Thread& current = current_thread();
if (current.started())
switch (current.state())
{
continue_thread(current.rsp(), current.rip());
}
else
{
current.set_started();
start_thread(current.rsp(), current.rip());
case Thread::State::NotStarted:
current.set_started();
start_thread(current.rsp(), current.rip());
case Thread::State::Executing:
continue_thread(current.rsp(), current.rip());
case Thread::State::Terminating:
ENABLE_INTERRUPTS();
current.on_exit();
ASSERT_NOT_REACHED();
}
ASSERT_NOT_REACHED();