From 0e225778d50865f2424dfb57d107630794721bcf Mon Sep 17 00:00:00 2001 From: dzwdz Date: Fri, 22 Apr 2022 15:24:22 +0200 Subject: kernel: recursive process_free --- src/kernel/main.c | 5 +++++ src/kernel/proc.c | 27 ++++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/kernel/main.c b/src/kernel/main.c index a0fdd07..14514cb 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -27,6 +27,11 @@ void shutdown(void) { for (size_t i = 0; i < sizeof(states) / sizeof(*states); i++) kprintf("state 0x%x: 0x%x\n", i, states[i]); + mem_debugprint(); + + // TODO generalize to process_cleanup + process_free(process_first); + mem_debugprint(); cpu_shutdown(); } diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 94a448a..b4f3493 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -70,13 +70,20 @@ struct process *process_fork(struct process *parent) { } void process_free(struct process *p) { - assert(p->state == PS_DEADER); - pagedir_free(p->pages); - if (p->child) { // TODO - // panic_invalid_state(); - return; - } - if (p->parent && p->parent->child == p) { + // TODO only attempt to free, return a bool + bool valid = false; + if (p->state == PS_DEADER) valid = true; + if (p->state == PS_DEAD && (!p->parent + || p->parent->state == PS_DEAD + || p->parent->state == PS_DEADER)) valid = true; + assert(valid); + + while (p->child) + process_free(p->child); + + if (p == process_first) return; + + if (p->parent->child == p) { p->parent->child = p->sibling; } else { // this would be simpler if siblings were a doubly linked list @@ -87,6 +94,7 @@ void process_free(struct process *p) { } prev->sibling = p->sibling; } + pagedir_free(p->pages); // TODO could be done on kill kfree(p); } @@ -274,6 +282,11 @@ int process_try2collect(struct process *dead) { return ret; + case PS_DEAD: + case PS_DEADER: + process_transition(dead, PS_DEADER); + return -1; + default: return -1; // this return value isn't used anywhere // TODO enforce that, somehow? idk -- cgit v1.2.3