From 53d21d1ccb75004d0085efedd688b695707a3138 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Fri, 6 May 2022 14:09:44 +0200
Subject: kernel/proc: reorganize the functions

---
 src/kernel/proc.c        | 190 ++++++++++++++++++++++-------------------------
 src/kernel/proc.h        |  21 +++---
 src/kernel/syscalls.c    |   4 +-
 src/kernel/vfs/request.c |   2 +-
 4 files changed, 103 insertions(+), 114 deletions(-)

(limited to 'src/kernel')

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;
-}
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 6266998..93044d2 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -56,27 +56,26 @@ struct process {
 extern struct process *process_first;
 extern struct process *process_current;
 
-// creates the root process
+/** Creates the root process. */
 struct process *process_seed(struct kmain_info *info);
 struct process *process_fork(struct process *parent, int flags);
 
-void process_forget(struct process *); // remove references to process
+void process_kill(struct process *proc, int ret);
+/** Tries to free a process / collect its return value. */
+int process_try2collect(struct process *dead);
 void process_free(struct process *);
-_Noreturn void process_switch_any(void); // switches to any running process
+/** Removes a process from the process tree. */
+void process_forget(struct process *);
+
+/** Switches execution to any running process. */
+_Noreturn void process_switch_any(void);
 
 /** Used for iterating over all processes */
 struct process *process_next(struct process *);
 
 struct process *process_find(enum process_state);
-size_t process_find_multiple(enum process_state, struct process **buf, size_t max);
 
-handle_t process_find_handle(struct process *proc, handle_t start_at); // finds the first free handle
+handle_t process_find_free_handle(struct process *proc, handle_t start_at);
 struct handle *process_handle_get(struct process *, handle_t, enum handle_type);
 
 void process_transition(struct process *, enum process_state);
-
-void process_kill(struct process *proc, int ret);
-
-/** Tries to transistion from PS_DEAD to PS_DEADER.
- * @return a nonnegative length of the quit message if successful, a negative val otherwise*/
-int process_try2collect(struct process *dead);
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index f3161e5..3443b60 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -51,7 +51,7 @@ handle_t _syscall_open(const char __user *path, int len) {
 
 	if (PATH_MAX < len)
 		SYSCALL_RETURN(-1);
-	if (process_find_handle(process_current, 0) < 0)
+	if (process_find_free_handle(process_current, 0) < 0)
 		SYSCALL_RETURN(-1);
 
 	path_buf = virt_cpy2kmalloc(process_current->pages, path, len);
@@ -184,7 +184,7 @@ handle_t _syscall_fs_fork2(void) {
 	struct process *child;
 	handle_t front;
 
-	front = process_find_handle(process_current, 1);
+	front = process_find_free_handle(process_current, 1);
 	if (front < 0) SYSCALL_RETURN(-1);
 	process_current->handles[front] = handle_init(HANDLE_FS_FRONT);
 
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index 516e6e0..d6f348a 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -35,7 +35,7 @@ void vfsreq_finish(struct vfs_request *req, int ret) {
 		// we need to wrap the id returned by the VFS in a handle passed to
 		// the client
 		if (req->caller) {
-			handle_t handle = process_find_handle(req->caller, 0);
+			handle_t handle = process_find_free_handle(req->caller, 0);
 			if (handle < 0)
 				panic_invalid_state(); // we check for free handles before the open() call
 
-- 
cgit v1.2.3