diff options
author | dzwdz | 2022-04-22 15:24:22 +0200 |
---|---|---|
committer | dzwdz | 2022-04-22 15:24:22 +0200 |
commit | 0e225778d50865f2424dfb57d107630794721bcf (patch) | |
tree | d48aa570979bccd793a63235f52a030c522dc0c6 /src/kernel/proc.c | |
parent | a60b3ca993ac7ff428c4a545c357484237450c22 (diff) |
kernel: recursive process_free
Diffstat (limited to 'src/kernel/proc.c')
-rw-r--r-- | src/kernel/proc.c | 27 |
1 files changed, 20 insertions, 7 deletions
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 |