summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/proc.c68
-rw-r--r--src/kernel/proc.h4
2 files changed, 53 insertions, 19 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 2a1d6fd..f17b94c 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -10,15 +10,17 @@
struct process *process_first;
struct process *process_current;
+static struct process *process_deadparent;
+
static uint32_t next_pid = 0;
struct process *process_seed(struct kmain_info *info) {
process_first = kmalloc(sizeof *process_first);
memset(process_first, 0, sizeof *process_first);
- process_first->state = PS_RUNNING;
- process_first->pages = pagedir_new();
- process_first->mount = vfs_mount_seed();
- process_first->id = next_pid++;
+ process_first->state = PS_RUNNING;
+ process_first->pages = pagedir_new();
+ process_first->mount = vfs_mount_seed();
+ process_first->id = next_pid++;
// map the stack to the last page in memory
pagedir_map(process_first->pages, (userptr_t)~PAGE_MASK, page_alloc(1), true, true);
@@ -37,6 +39,13 @@ struct process *process_seed(struct kmain_info *info) {
true, true);
process_first->regs.eip = init_base;
+ process_deadparent = kmalloc(sizeof *process_deadparent);
+ memset(process_deadparent, 0, sizeof *process_deadparent);
+ process_deadparent->state = PS_DUMMY;
+ process_deadparent->id = next_pid++;
+
+ process_first->sibling = process_deadparent;
+
return process_first;
}
@@ -60,19 +69,8 @@ struct process *process_fork(struct process *parent) {
return child;
}
-void process_free(struct process *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;
+void process_forget(struct process *p) {
+ assert(p->parent);
if (p->parent->child == p) {
p->parent->child = p->sibling;
@@ -85,6 +83,22 @@ void process_free(struct process *p) {
}
prev->sibling = p->sibling;
}
+}
+
+void process_free(struct process *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->parent) return;
+ process_forget(p);
pagedir_free(p->pages); // TODO could be done on kill
kfree(p);
}
@@ -211,7 +225,9 @@ void process_transition(struct process *p, enum process_state state) {
assert(last == PS_WAITS4FS);
break;
- case PS_LAST: panic_invalid_state();
+ case PS_DUMMY:
+ case PS_LAST:
+ panic_invalid_state();
}
}
@@ -238,8 +254,11 @@ void process_kill(struct process *p, int ret) {
}
// TODO VULN unbounded recursion
- for (struct process *c = p->child; c; c = c->sibling)
+ struct process *c2;
+ for (struct process *c = p->child; c; c = c2) {
+ c2 = c->sibling;
process_kill(c, -1);
+ }
switch (p->state) {
case PS_RUNNING:
@@ -249,7 +268,17 @@ void process_kill(struct process *p, int ret) {
case PS_WAITS4FS:
// if the request wasn't accepted we could just remove this process from the queue
case PS_WAITS4IRQ:
+ /* instead of killing the process outright, we mark it to get killed
+ * as soon as it becomes running and we try to give it control.
+ *
+ * we also reparent it to process_deadparent because we don't want
+ * dead processes to have any alive children */
+ // TODO process_reparent?
p->deathbed = true;
+ process_forget(p);
+ p->sibling = process_deadparent->child;
+ p->parent = process_deadparent;
+ process_deadparent->child = p;
return;
case PS_WAITS4REQUEST:
@@ -260,6 +289,7 @@ void process_kill(struct process *p, int ret) {
case PS_DEAD:
case PS_DEADER:
+ case PS_DUMMY:
case PS_LAST:
kprintf("process_kill unexpected state 0x%x\n", p->state);
panic_invalid_state();
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 7389b74..4fabe0e 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -13,6 +13,8 @@ enum process_state {
PS_WAITS4FS,
PS_WAITS4REQUEST,
PS_WAITS4IRQ, // set by root vfs
+
+ PS_DUMMY,
PS_LAST,
};
@@ -62,6 +64,8 @@ extern struct process *process_current;
// creates the root process
struct process *process_seed(struct kmain_info *info);
struct process *process_fork(struct process *parent);
+
+void process_forget(struct process *); // remove references to process
void process_free(struct process *);
_Noreturn void process_switch_any(void); // switches to any running process