diff --git a/include/sys/thread.h b/include/sys/thread.h index 3f20b07..ee8e629 100644 --- a/include/sys/thread.h +++ b/include/sys/thread.h @@ -16,6 +16,9 @@ enum thread_state { THREAD_STOPPED }; +#define THREAD_KERNEL (1 << 0) +#define THREAD_EMPTY (1 << 1) + #define thread_signal_clear(thr, signum) \ (thr)->sigq &= ~(1ULL << ((signum) - 1)) #define thread_signal_set(thr, signum) \ @@ -44,6 +47,7 @@ struct thread { // State char name[256]; + uint32_t flags; pid_t pid; pid_t pgid; enum thread_state state; @@ -62,6 +66,7 @@ struct thread { pid_t thread_alloc_pid(int is_user); void thread_ioctx_fork(struct thread *dst, struct thread *src); int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user); +void thread_cleanup(struct thread *thr); struct thread *thread_find(pid_t pid); void thread_signal(struct thread *thr, int signum); diff --git a/sys/thread.c b/sys/thread.c index 13c9f5a..129b77f 100644 --- a/sys/thread.c +++ b/sys/thread.c @@ -113,6 +113,29 @@ struct thread *thread_child(struct thread *of, pid_t pid) { return NULL; } +void thread_cleanup(struct thread *thr) { + _assert(thr); + // Leave only the system context required for hierachy tracking and error code/pid + thr->state = THREAD_STOPPED; + thr->flags |= THREAD_EMPTY; + kinfo("Cleaning up %d\n", thr->pid); + for (size_t i = 0; i < THREAD_MAX_FDS; ++i) { + if (thr->fds[i]) { + vfs_close(&thr->ioctx, thr->fds[i]); + + _assert(thr->fds[i]->refcount >= 0); + if (thr->fds[i]->refcount == 0) { + kfree(thr->fds[i]); + } + + thr->fds[i] = NULL; + } + } + + // Release userspace pages + mm_space_release(thr->space); +} + int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user) { uintptr_t stack_pages = amd64_phys_alloc_contiguous(2); _assert(stack_pages != MM_NADDR); @@ -121,6 +144,7 @@ int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user) { thr->data.rsp0_size = MM_PAGE_SIZE * 2; thr->data.rsp0_top = thr->data.rsp0_base + thr->data.rsp0_size; thr->name[0] = 0; + thr->flags = user ? 0 : THREAD_KERNEL; uint64_t *stack = (uint64_t *) (thr->data.rsp0_base + thr->data.rsp0_size); @@ -254,6 +278,7 @@ int sys_fork(struct sys_fork_frame *frame) { dst->data.rsp0_base = MM_VIRTUALIZE(stack_pages); dst->data.rsp0_size = MM_PAGE_SIZE * 2; dst->data.rsp0_top = dst->data.rsp0_base + dst->data.rsp0_size; + dst->flags = 0; mm_space_t space = amd64_mm_pool_alloc(); mm_space_fork(space, src->space, MM_CLONE_FLG_KERNEL | MM_CLONE_FLG_USER); @@ -435,6 +460,7 @@ int sys_execve(const char *path, const char **argv, const char **envp) { thr->space = amd64_mm_pool_alloc(); _assert(thr->space); thr->data.cr3 = MM_PHYS(thr->space); + thr->flags = 0; mm_space_clone(thr->space, mm_kernel, MM_CLONE_FLG_KERNEL); } else { @@ -498,6 +524,10 @@ __attribute__((noreturn)) void sys_exit(int status) { thread_signal(thr->parent, SIGCHLD); } + // Sure that no code of this thread will be running anymore - + // can clean up its stuff + thread_cleanup(thr); + sched_unqueue(thr, THREAD_STOPPED); panic("This code shouldn't run\n"); } @@ -751,7 +781,7 @@ int sys_brk(void *addr) { } } - //thr->brk = (uintptr_t) addr; + thr->brk = (uintptr_t) addr; return 0; }