summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2022-04-22 15:24:22 +0200
committerdzwdz2022-04-22 15:24:22 +0200
commit0e225778d50865f2424dfb57d107630794721bcf (patch)
treed48aa570979bccd793a63235f52a030c522dc0c6 /src/kernel
parenta60b3ca993ac7ff428c4a545c357484237450c22 (diff)
kernel: recursive process_free
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/main.c5
-rw-r--r--src/kernel/proc.c27
2 files changed, 25 insertions, 7 deletions
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
@@ -28,5 +28,10 @@ void shutdown(void) {
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