Kernel: Restructure process and thread termination
When we want to kill a process, we mark its threads as Terminating or Terminated. If the thread is in critical section that has to be finished, it will be in Terminating state until done. Once Scheduler is trying to execute Terminated thread it will instead delete it. Once processes last thread is marked Terminated, the processes will turn it into a cleanup thread, that will allow blocks and memory cleanup to be done.
This commit is contained in:
@@ -41,8 +41,9 @@ namespace Kernel
|
||||
static Process* create_kernel(entry_t, void*);
|
||||
static BAN::ErrorOr<Process*> create_userspace(const Credentials&, BAN::StringView);
|
||||
~Process();
|
||||
void cleanup_function();
|
||||
|
||||
[[noreturn]] void exit(int status);
|
||||
void exit(int status);
|
||||
|
||||
void add_thread(Thread*);
|
||||
void on_thread_exit(Thread&);
|
||||
|
||||
@@ -20,9 +20,6 @@ namespace Kernel
|
||||
void reschedule_if_idling();
|
||||
|
||||
void set_current_thread_sleeping(uint64_t);
|
||||
[[noreturn]] void set_current_thread_done();
|
||||
|
||||
[[noreturn]] void set_current_process_done();
|
||||
|
||||
void block_current_thread(Semaphore*);
|
||||
void unblock_threads(Semaphore*);
|
||||
@@ -33,6 +30,8 @@ namespace Kernel
|
||||
|
||||
static bool is_valid_tid(pid_t tid);
|
||||
|
||||
[[noreturn]] void delete_current_process_and_thread();
|
||||
|
||||
private:
|
||||
Scheduler() = default;
|
||||
|
||||
@@ -76,6 +75,7 @@ namespace Kernel
|
||||
|
||||
uint64_t m_last_reschedule = 0;
|
||||
|
||||
friend class Thread;
|
||||
friend class Process;
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,16 @@ namespace Kernel
|
||||
NotStarted,
|
||||
Executing,
|
||||
Terminating,
|
||||
Terminated
|
||||
};
|
||||
|
||||
class TerminateBlocker
|
||||
{
|
||||
public:
|
||||
TerminateBlocker(Thread&);
|
||||
~TerminateBlocker();
|
||||
private:
|
||||
Thread& m_thread;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -36,6 +46,7 @@ namespace Kernel
|
||||
|
||||
BAN::ErrorOr<Thread*> clone(Process*, uintptr_t rsp, uintptr_t rip);
|
||||
void setup_exec();
|
||||
void setup_process_cleanup();
|
||||
|
||||
bool has_signal_to_execute() const;
|
||||
void set_signal_done(int signal);
|
||||
@@ -55,8 +66,8 @@ namespace Kernel
|
||||
uintptr_t rip() const { return m_rip; }
|
||||
|
||||
void set_started() { ASSERT(m_state == State::NotStarted); m_state = State::Executing; }
|
||||
void set_terminating();
|
||||
State state() const { return m_state; }
|
||||
void terminate() { m_state = State::Terminating; }
|
||||
|
||||
vaddr_t stack_base() const { return m_stack->vaddr(); }
|
||||
size_t stack_size() const { return m_stack->size(); }
|
||||
@@ -103,6 +114,9 @@ namespace Kernel
|
||||
int m_handling_signal { 0 };
|
||||
static_assert(_SIGMAX < 64);
|
||||
|
||||
uint64_t m_terminate_blockers { 0 };
|
||||
|
||||
friend class TerminateBlocker;
|
||||
friend class Scheduler;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user