forked from Bananymous/banan-os
Kernel: Threads can now be terminated mid execution
This commit is contained in:
parent
32359df939
commit
e704968f96
|
@ -15,7 +15,6 @@ start_thread:
|
||||||
movl 8(%esp), %ecx
|
movl 8(%esp), %ecx
|
||||||
movl 4(%esp), %esp
|
movl 4(%esp), %esp
|
||||||
movl $0, %ebp
|
movl $0, %ebp
|
||||||
movl $0, (%esp)
|
|
||||||
pushl $exit_thread_trampoline
|
pushl $exit_thread_trampoline
|
||||||
sti
|
sti
|
||||||
jmp *%ecx
|
jmp *%ecx
|
||||||
|
|
|
@ -14,7 +14,6 @@ start_thread:
|
||||||
movq %rdi, %rsp
|
movq %rdi, %rsp
|
||||||
popq %rdi
|
popq %rdi
|
||||||
movq $0, %rbp
|
movq $0, %rbp
|
||||||
movq $0, (%rsp)
|
|
||||||
pushq $exit_thread_trampoline
|
pushq $exit_thread_trampoline
|
||||||
sti
|
sti
|
||||||
jmp *%rsi
|
jmp *%rsi
|
||||||
|
|
|
@ -23,9 +23,11 @@ namespace Kernel
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<BAN::RefPtr<Process>> create_kernel(entry_t, void*);
|
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&);
|
void on_thread_exit(Thread&);
|
||||||
|
|
||||||
BAN::ErrorOr<void> init_stdio();
|
BAN::ErrorOr<void> init_stdio();
|
||||||
|
|
|
@ -18,6 +18,13 @@ namespace Kernel
|
||||||
public:
|
public:
|
||||||
using entry_t = void(*)(void*);
|
using entry_t = void(*)(void*);
|
||||||
|
|
||||||
|
enum class State
|
||||||
|
{
|
||||||
|
NotStarted,
|
||||||
|
Executing,
|
||||||
|
Terminating,
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<Thread*> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr);
|
static BAN::ErrorOr<Thread*> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr);
|
||||||
~Thread();
|
~Thread();
|
||||||
|
@ -29,8 +36,9 @@ namespace Kernel
|
||||||
uintptr_t rsp() const { return m_rsp; }
|
uintptr_t rsp() const { return m_rsp; }
|
||||||
uintptr_t rip() const { return m_rip; }
|
uintptr_t rip() const { return m_rip; }
|
||||||
|
|
||||||
void set_started() { m_started = true; }
|
void set_started() { ASSERT(m_state == State::NotStarted); m_state = State::Executing; }
|
||||||
bool started() const { return m_started; }
|
State state() const { return m_state; }
|
||||||
|
void terminate() { m_state = State::Terminating; }
|
||||||
|
|
||||||
static Thread& current() ;
|
static Thread& current() ;
|
||||||
BAN::RefPtr<Process> process();
|
BAN::RefPtr<Process> process();
|
||||||
|
@ -46,8 +54,10 @@ namespace Kernel
|
||||||
uintptr_t m_rip = 0;
|
uintptr_t m_rip = 0;
|
||||||
uintptr_t m_rsp = 0;
|
uintptr_t m_rsp = 0;
|
||||||
const pid_t m_tid = 0;
|
const pid_t m_tid = 0;
|
||||||
bool m_started = false;
|
State m_state { State::NotStarted };
|
||||||
BAN::RefPtr<Process> m_process;
|
BAN::RefPtr<Process> m_process;
|
||||||
|
|
||||||
|
friend class Scheduler;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,7 +23,12 @@ namespace Kernel
|
||||||
, m_tty(TTY::current())
|
, 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));
|
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())
|
if (auto res = Scheduler::get().add_thread(thread); res.is_error())
|
||||||
{
|
{
|
||||||
m_threads.pop_back();
|
m_threads.pop_back();
|
||||||
return res;
|
return res.release_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::on_thread_exit(Thread& thread)
|
void Process::on_thread_exit(Thread& thread)
|
||||||
|
@ -46,6 +51,17 @@ namespace Kernel
|
||||||
m_threads.remove(i);
|
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()
|
BAN::ErrorOr<void> Process::init_stdio()
|
||||||
{
|
{
|
||||||
if (!m_open_files.empty())
|
if (!m_open_files.empty())
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
extern "C" void start_thread(uintptr_t rsp, uintptr_t rip);
|
extern "C" [[noreturn]] void start_thread(uintptr_t rsp, uintptr_t rip);
|
||||||
extern "C" void continue_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();
|
extern "C" uintptr_t read_rip();
|
||||||
|
|
||||||
static Scheduler* s_instance = nullptr;
|
static Scheduler* s_instance = nullptr;
|
||||||
|
@ -166,14 +166,17 @@ namespace Kernel
|
||||||
|
|
||||||
Thread& current = current_thread();
|
Thread& current = current_thread();
|
||||||
|
|
||||||
if (current.started())
|
switch (current.state())
|
||||||
{
|
{
|
||||||
continue_thread(current.rsp(), current.rip());
|
case Thread::State::NotStarted:
|
||||||
}
|
current.set_started();
|
||||||
else
|
start_thread(current.rsp(), current.rip());
|
||||||
{
|
case Thread::State::Executing:
|
||||||
current.set_started();
|
continue_thread(current.rsp(), current.rip());
|
||||||
start_thread(current.rsp(), current.rip());
|
case Thread::State::Terminating:
|
||||||
|
ENABLE_INTERRUPTS();
|
||||||
|
current.on_exit();
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
|
Loading…
Reference in New Issue