Add thread cleanup after termination

This commit is contained in:
Mark
2019-12-29 14:15:09 +02:00
parent 2681fec924
commit ccc13ef0d5
7 changed files with 64 additions and 5 deletions
+2
View File
@@ -11,6 +11,8 @@ struct amd64_thread {
uintptr_t stack3_base;
uintptr_t stack3_size;
uint32_t data_flags;
};
void amd64_thread_set_ip(struct thread *t, uintptr_t ip);
+1
View File
@@ -45,3 +45,4 @@ int thread_init(struct thread *t,
size_t stack3_size,
uint32_t flags,
void *arg);
void thread_cleanup(struct thread *t);
+6 -1
View File
@@ -282,7 +282,7 @@ int mm_space_fork(mm_space_t dst_pml4, const mm_space_t src_pml4, uint32_t flags
}
void mm_space_release(mm_space_t pml4) {
for (size_t pml4i = 0; pml4i < 255; ++pml4i) {
for (size_t pml4i = 0; pml4i < AMD64_PML4I_USER_END; ++pml4i) {
if (!(pml4[pml4i] & 1)) {
continue;
}
@@ -324,6 +324,11 @@ void mm_space_release(mm_space_t pml4) {
}
}
void mm_space_free(mm_space_t pml4) {
mm_space_release(pml4);
amd64_mm_pool_free(pml4);
}
static void amd64_mm_describe_range(const mm_space_t pml4, uintptr_t start_addr, uintptr_t end_addr) {
uintptr_t addr = AMD64_MM_STRIPSX(start_addr);
+2
View File
@@ -230,6 +230,8 @@ void sched_remove_from(int cpu, struct thread *thr) {
thr->next = NULL;
thr->prev = NULL;
thread_cleanup(thr);
// TODO: make other cpus schedule a new thread if they're running a stopped one
}
+30
View File
@@ -28,12 +28,16 @@ int thread_init(
size_t rsp3_size,
uint32_t flags,
void *arg) {
t->data.data_flags = 0;
if (!rsp0_base) {
void *kstack = kmalloc(THREAD_KSTACK_SIZE);
_assert(kstack);
rsp0_base = (uintptr_t) kstack;
rsp0_size = THREAD_KSTACK_SIZE;
} else {
t->data.data_flags |= 1 /* Don't free kstack */;
}
if (!(flags & THREAD_KERNEL) && !rsp3_base) {
@@ -44,6 +48,8 @@ int thread_init(
rsp3_size = 4 * 0x1000;
kdebug("Allocated user stack: %p\n", ustack);
} else if (rsp3_base) {
t->data.data_flags |= 2 /* Don't free ustack */;
}
t->data.stack0_base = rsp0_base;
@@ -112,6 +118,29 @@ int thread_init(
return 0;
}
void thread_cleanup(struct thread *t) {
_assert(t);
// Release files
for (size_t i = 0; i < 4; ++i) {
if (t->fds[i].vnode) {
vfs_close(&t->ioctx, &t->fds[i]);
}
}
// Release stacks
if (!(t->data.data_flags & 1)) {
kfree((void *) t->data.stack0_base);
}
if (t->space != mm_kernel) {
mm_space_free(t->space);
}
memset(t, 0, sizeof(struct thread));
kfree(t);
}
int sys_execve(const char *filename, const char *const argv[], const char *const envp[]) {
asm volatile ("cli");
struct thread *thr = get_cpu()->thread;
@@ -211,6 +240,7 @@ int sys_fork(void) {
struct amd64_thread *dst_data = &thr_dst->data;
_assert(dst_kstack);
dst_data->data_flags |= 1 /* Don't free kstack */;
dst_data->stack0_base = (uintptr_t) dst_kstack;
dst_data->stack0_size = THREAD_KSTACK_SIZE;
dst_data->stack3_base = thr_src->data.stack3_base;
+7
View File
@@ -67,6 +67,9 @@ void vnode_ref(vnode_t *vn) {
// vfs_vnode_path(buf, vn);
// printf("++refcount for %s\n", buf);
_assert(vn);
if (vn->type == VN_BLK || vn->type == VN_CHR) {
return;
}
_assert(vn->fs);
_assert(vn->fs->cls);
@@ -86,6 +89,10 @@ void vnode_ref(vnode_t *vn) {
void vnode_unref(vnode_t *vn) {
_assert(vn);
if (vn->type == VN_BLK || vn->type == VN_CHR) {
return;
}
_assert(vn->fs);
_assert(vn->fs->cls);
+16 -4
View File
@@ -868,12 +868,24 @@ int vfs_open_node(struct vfs_ioctx *ctx, struct ofile *of, vnode_t *vn, int opt)
void vfs_close(struct vfs_ioctx *ctx, struct ofile *of) {
_assert(of);
kinfo("vfs_close %p\n", of);
vnode_t *vn = of->vnode;
_assert(vn && vn->op);
switch (vn->type) {
case VN_REG:
case VN_DIR:
_assert(vn);
if (vn->op->close) {
vn->op->close(of);
if (vn->op->close) {
vn->op->close(of);
}
break;
// TODO: maybe call something special for that
case VN_CHR:
case VN_BLK:
break;
default:
panic("Unhandled vnode type\n");
}
vnode_unref(of->vnode);