diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/proc.c | 40 | ||||
-rw-r--r-- | src/kernel/proc.h | 3 |
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); |