summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-04-12 21:04:18 +0200
committerdzwdz2022-04-12 21:04:18 +0200
commitea59ff29ab98d363b48bfb22be02a4823b765c32 (patch)
tree909f5f1a131892defcf9dd82cb4da3f2b7afe21c /src
parent49d095e34b9d9a364437bb3b1b6b1e7b07328d38 (diff)
kernel/proc: implement `process_next` for simple process iteration
Diffstat (limited to 'src')
-rw-r--r--src/kernel/proc.c40
-rw-r--r--src/kernel/proc.h3
2 files changed, 28 insertions, 15 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 944f5b9..ca1b2ec 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -95,21 +95,24 @@ _Noreturn void process_idle(void) {
}
}
-// TODO there's no check for going past the stack - VULN
-static size_t _process_find_recursive(
- enum process_state target, struct process *iter,
- struct process **buf, size_t pos, size_t max)
-{
- while (pos < max && iter) {
- if (iter->state == target)
- buf[pos++] = iter;
-
- // DFS
- pos = _process_find_recursive(target, iter->child, buf, pos, max);
-
- iter = iter->sibling;
+struct process *process_next(struct process *p) {
+ /* is a weird depth-first search, the search order is:
+ * 1
+ * / \
+ * 2 5
+ * /| |\
+ * 3 4 6 7
+ */
+ if (!p) return NULL;
+ if (p->child) return p->child;
+ if (p->sibling) return p->sibling;
+
+ /* looking at the diagram above - we're at 4, want to find 5 */
+ while (!p->sibling) {
+ p = p->parent;
+ if (!p) return NULL;
}
- return pos;
+ return p->sibling;
}
struct process *process_find(enum process_state target) {
@@ -119,7 +122,14 @@ struct process *process_find(enum process_state target) {
}
size_t process_find_multiple(enum process_state target, struct process **buf, size_t max) {
- return _process_find_recursive(target, process_first, buf, 0, 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;
+ }
+ return i;
}
handle_t process_find_handle(struct process *proc) {
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index d754522..1d84b7f 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -64,6 +64,9 @@ _Noreturn void process_switch_any(void); // switches to any running process
/** If there are any processes waiting for IRQs, wait with them. Otherwise, shut down */
_Noreturn void process_idle(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);