summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2022-04-21 19:05:31 +0200
committerdzwdz2022-04-21 19:05:31 +0200
commit0ae12266b7160272fd95875006c6c1b6d6b1dcd2 (patch)
tree1787cb9da8109185a3f9d8c28009a5ca3962364b /src/kernel
parentd1af67ca27b1cf044244e61071fe2e538e452815 (diff)
kernel/proc: only kill deathbedded processes on switch attempt
this makes `process_transition` safe again, as it won't be able to free processes. it was a pretty unintuitive behaviour
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/proc.c12
-rw-r--r--src/kernel/proc.h2
2 files changed, 6 insertions, 8 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 9e8e4c5..175377e 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -84,8 +84,13 @@ void process_free(struct process *p) {
kfree(p);
}
+// TODO make process_switch private
void process_switch(struct process *proc) {
assert(proc->state == PS_RUNNING);
+ if (proc->deathbed) {
+ process_kill(proc, -1);
+ process_switch_any();
+ }
process_current = proc;
pagedir_switch(proc->pages);
sysexit(proc->regs);
@@ -169,13 +174,6 @@ void process_transition(struct process *p, enum process_state state) {
switch (state) {
case PS_RUNNING:
assert(last != PS_DEAD && last != PS_DEADER);
- if (p->deathbed)
- process_kill(p, -1);
- /* TODO return something to warn caller if deathbedded, to prevent
- * use after free
- *
- * alternatively assert(!p->deathbed); and move the responsibility
- * to the caller */
break;
case PS_DEAD:
// see process_kill
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 255a9af..9304f28 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -21,7 +21,7 @@ struct process {
struct registers regs;
enum process_state state;
- bool deathbed; // kill instead of switching to PS_RUNNING
+ bool deathbed; // kill on next process_switch attempt
struct process *sibling;
struct process *child;