summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-04-14 12:36:34 +0200
committerdzwdz2022-04-14 12:36:34 +0200
commit0d59c8d11173b28f958413128eb792655568a365 (patch)
tree4750ee37a845bdae8f9fbc85eb6baa80fdc7a8cc /src
parent18d757e1b4939b24031935a6db59aefee4669e68 (diff)
kernel: store a pointer to the callback function in .waits4irq
removes `proc.c`'s pointless dependency on `vfs/root.h`
Diffstat (limited to 'src')
-rw-r--r--src/kernel/proc.c3
-rw-r--r--src/kernel/proc.h1
-rw-r--r--src/kernel/vfs/root.c39
3 files changed, 22 insertions, 21 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 2c4cc5c..e97d5cf 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -6,7 +6,6 @@
#include <kernel/vfs/mount.h>
#include <shared/mem.h>
#include <stdint.h>
-#include <kernel/vfs/root.h> // TODO
struct process *process_first;
struct process *process_current;
@@ -108,7 +107,7 @@ _Noreturn void process_idle(void) {
if (procs[i]->waits4irq.ready()) {
/* if this is entered during the first iteration, it indicates a
* kernel bug. this should be logged. TODO? */
- vfs_root_handler(&procs[i]->waits4irq.req); // TODO this should be a function pointer too
+ procs[i]->waits4irq.callback(procs[i]);
process_switch_any();
}
}
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index eaa649a..5daef31 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -40,6 +40,7 @@ struct process {
struct {
struct vfs_request req;
bool (*ready)();
+ void (*callback)(struct process *);
} waits4irq;
};
struct vfs_request *handled_req;
diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c
index 4e49c3c..cdc388f 100644
--- a/src/kernel/vfs/root.c
+++ b/src/kernel/vfs/root.c
@@ -7,6 +7,7 @@
#include <kernel/util.h>
#include <kernel/vfs/root.h>
#include <shared/mem.h>
+#include <stdbool.h>
// TODO move to arch/
@@ -47,6 +48,23 @@ static void req_preprocess(struct vfs_request *req, size_t max_len) {
assert(req->input.len + req->offset <= max_len);
}
+
+static void wait_callback(struct process *proc) {
+ vfs_root_handler(&proc->waits4irq.req);
+}
+
+static bool wait_setup(struct vfs_request *req, bool *ready, bool (*ready_fn)()) {
+ if (!ready_fn()) {
+ *ready = false;
+ req->caller->state = PS_WAITS4IRQ;
+ req->caller->waits4irq.req = *req;
+ req->caller->waits4irq.ready = ready_fn;
+ req->caller->waits4irq.callback = wait_callback;
+ return true;
+ }
+ return false;
+}
+
static int handle(struct vfs_request *req, bool *ready) {
switch (req->type) {
case VFSOP_OPEN:
@@ -88,31 +106,14 @@ static int handle(struct vfs_request *req, bool *ready) {
return req->output.len;
}
case HANDLE_COM1: {
- // yet another bit of code shared between serial and ps2.
- // i really should think how i could unite both of those
- if (!serial_ready()) {
- *ready = false;
- req->caller->state = PS_WAITS4IRQ;
- req->caller->waits4irq.req = *req;
- req->caller->waits4irq.ready = serial_ready;
- return -1;
- }
+ if (wait_setup(req, ready, serial_ready)) return -1;
char buf[16];
size_t len = serial_read(buf, min(req->output.len, sizeof buf));
virt_cpy_to(req->caller->pages, req->output.buf, buf, len);
return len;
}
case HANDLE_PS2: {
- if (!ps2_ready()) {
- *ready = false;
- req->caller->state = PS_WAITS4IRQ;
- /* not copying any memory, both sides point to the same
- * struct. this line's only there so i don't depend on
- * struct alignment always staying the same */
- req->caller->waits4irq.req = *req;
- req->caller->waits4irq.ready = ps2_ready;
- return -1;
- }
+ if (wait_setup(req, ready, ps2_ready)) return -1;
uint8_t buf[16];
size_t len = ps2_read(buf, min(req->output.len, sizeof buf));
virt_cpy_to(req->caller->pages, req->output.buf, buf, len);