summaryrefslogtreecommitdiff
path: root/src/kernel/proc.c
diff options
context:
space:
mode:
authordzwdz2022-05-06 14:09:44 +0200
committerdzwdz2022-05-06 14:09:44 +0200
commit53d21d1ccb75004d0085efedd688b695707a3138 (patch)
tree90129714fc02259bfef7faeb91b1aa07fd03cac1 /src/kernel/proc.c
parent38dd7bb947eb94ee77bf2ea3ccf16a326b991359 (diff)
kernel/proc: reorganize the functions
Diffstat (limited to 'src/kernel/proc.c')
-rw-r--r--src/kernel/proc.c190
1 files changed, 90 insertions, 100 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 3233725..ed257fd 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -74,6 +74,92 @@ struct process *process_fork(struct process *parent, int flags) {
return child;
}
+void process_kill(struct process *p, int ret) {
+ if (p->state != PS_DEAD) {
+ if (p->handled_req) {
+ vfsreq_finish(p->handled_req, -1);
+ p->handled_req = NULL;
+ }
+
+ if (p->controlled) {
+ // TODO vfs_backend_user_handlerdown
+ assert(p->controlled->potential_handlers > 0);
+ p->controlled->potential_handlers--;
+ if (p->controlled->potential_handlers == 0) {
+ // orphaned
+ struct vfs_request *q = p->controlled->queue;
+ while (q) {
+ struct vfs_request *q2 = q->queue_next;
+ vfsreq_finish(q, -1);
+ q = q2;
+ }
+ p->controlled->queue = NULL;
+ }
+ if (p->controlled->user.handler == p) {
+ assert(p->state == PS_WAITS4REQUEST);
+ p->controlled->user.handler = NULL;
+ }
+
+ vfs_backend_refdown(p->controlled);
+ p->controlled = NULL;
+ }
+
+ if (p->state == PS_WAITS4FS)
+ p->waits4fs.req->caller = NULL;
+
+ for (handle_t h = 0; h < HANDLE_MAX; h++)
+ handle_close(p->handles[h]);
+
+ vfs_mount_remref(p->mount);
+ p->mount = NULL;
+
+ process_transition(p, PS_DEAD);
+ p->death_msg = ret;
+
+ if (p->parent)
+ pagedir_free(p->pages); // TODO put init's pages in the allocator
+
+ // TODO VULN unbounded recursion
+ struct process *c2;
+ for (struct process *c = p->child; c; c = c2) {
+ c2 = c->sibling;
+ process_kill(c, -1);
+ }
+ }
+
+ assert(!p->child);
+ process_try2collect(p);
+
+ if (p == process_first) shutdown();
+}
+
+int process_try2collect(struct process *dead) {
+ struct process *parent = dead->parent;
+ int ret = -1;
+
+ assert(dead && dead->state == PS_DEAD);
+
+ if (!dead->noreap && parent && parent->state != PS_DEAD) { // might be reaped
+ if (parent->state != PS_WAITS4CHILDDEATH) return -1;
+
+ ret = dead->death_msg;
+ regs_savereturn(&parent->regs, ret);
+ process_transition(parent, PS_RUNNING);
+ }
+
+ process_free(dead);
+ return ret;
+}
+
+void process_free(struct process *p) {
+ assert(p->state == PS_DEAD);
+ assert(!p->child);
+
+ if (!p->parent) return;
+ process_forget(p);
+ kfree(p);
+}
+
void process_forget(struct process *p) {
assert(p->parent);
@@ -90,15 +176,6 @@ void process_forget(struct process *p) {
}
}
-void process_free(struct process *p) {
- assert(p->state == PS_DEAD);
- assert(!p->child);
-
- if (!p->parent) return;
- process_forget(p);
- kfree(p);
-}
-
static _Noreturn void process_switch(struct process *proc) {
assert(proc->state == PS_RUNNING);
process_current = proc;
@@ -138,23 +215,13 @@ struct process *process_next(struct process *p) {
}
struct process *process_find(enum process_state target) {
- struct process *result = NULL;
- process_find_multiple(target, &result, 1);
- return result;
-}
-
-size_t process_find_multiple(enum process_state target, struct process **buf, size_t max) {
- size_t i = 0;
- for (struct process *p = process_first;
- i < max && p;
- p = process_next(p))
- {
- if (p->state == target) buf[i++] = p;
+ for (struct process *p = process_first; p; p = process_next(p)) {
+ if (p->state == target) return p;
}
- return i;
+ return NULL;
}
-handle_t process_find_handle(struct process *proc, handle_t start_at) {
+handle_t process_find_free_handle(struct process *proc, handle_t start_at) {
// TODO start_at is a bit of a hack
handle_t handle;
for (handle = start_at; handle < HANDLE_MAX; handle++) {
@@ -194,80 +261,3 @@ void process_transition(struct process *p, enum process_state state) {
panic_invalid_state();
}
}
-
-void process_kill(struct process *p, int ret) {
- if (p->state != PS_DEAD) {
- if (p->handled_req) {
- vfsreq_finish(p->handled_req, -1);
- p->handled_req = NULL;
- }
-
- if (p->controlled) {
- // TODO vfs_backend_user_handlerdown
- assert(p->controlled->potential_handlers > 0);
- p->controlled->potential_handlers--;
- if (p->controlled->potential_handlers == 0) {
- // orphaned
- struct vfs_request *q = p->controlled->queue;
- while (q) {
- struct vfs_request *q2 = q->queue_next;
- vfsreq_finish(q, -1);
- q = q2;
- }
- p->controlled->queue = NULL;
- }
- if (p->controlled->user.handler == p) {
- assert(p->state == PS_WAITS4REQUEST);
- p->controlled->user.handler = NULL;
- }
-
- vfs_backend_refdown(p->controlled);
- p->controlled = NULL;
- }
-
- if (p->state == PS_WAITS4FS)
- p->waits4fs.req->caller = NULL;
-
- for (handle_t h = 0; h < HANDLE_MAX; h++)
- handle_close(p->handles[h]);
-
- vfs_mount_remref(p->mount);
- p->mount = NULL;
-
- process_transition(p, PS_DEAD);
- p->death_msg = ret;
-
- if (p->parent)
- pagedir_free(p->pages); // TODO put init's pages in the allocator
-
- // TODO VULN unbounded recursion
- struct process *c2;
- for (struct process *c = p->child; c; c = c2) {
- c2 = c->sibling;
- process_kill(c, -1);
- }
- }
-
- assert(!p->child);
- process_try2collect(p);
-
- if (p == process_first) shutdown();
-}
-
-int process_try2collect(struct process *dead) {
- struct process *parent = dead->parent;
- int ret = -1;
-
- assert(dead && dead->state == PS_DEAD);
-
- if (!dead->noreap && parent && parent->state != PS_DEAD) { // might be reaped
- if (parent->state != PS_WAITS4CHILDDEATH) return -1;
-
- ret = dead->death_msg;
- regs_savereturn(&parent->regs, ret);
- process_transition(parent, PS_RUNNING);
- }
-
- process_free(dead);
- return ret;
-}