diff options
author | dzwdz | 2024-07-14 19:19:35 +0200 |
---|---|---|
committer | dzwdz | 2024-07-14 19:19:35 +0200 |
commit | 6fe8073de975ad7722043f9173fec068178e2eac (patch) | |
tree | 9427bb0368e25609eea66fa52567b57522b0e0aa /src/kernel/vfs | |
parent | b3a86647b644db30f5fd70bd651c44f681962a9b (diff) |
kernel: rework postqueue
Keeping its old name for now to make things easier for myself.
This might just be replaced by sys/queue.h soon.
Diffstat (limited to 'src/kernel/vfs')
-rw-r--r-- | src/kernel/vfs/request.c | 59 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 12 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index d4ea16c..8f44afb 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -242,3 +242,62 @@ vfsback_provdown(VfsBackend *b) } vfsback_checkfree(b); } + +void +postqueue_init(ReqQueue *q) +{ + q->head = NULL; +} + +void +postqueue_join(ReqQueue *q, VfsReq *req) +{ + if (req->postqueue_next) + panic_invalid_state(); + + VfsReq **it = &q->head; + while (*it != NULL) { + it = &(*it)->postqueue_next; + } + *it = req; +} + +VfsReq * +postqueue_pop(ReqQueue *q) +{ + VfsReq *req = q->head; + if (req) { + q->head = req->postqueue_next; + req->postqueue_next = NULL; + } + return req; +} + +void +postqueue_ringreadall(ReqQueue *q, ring_t *r) +{ + VfsReq **queue = &q->head; /* whatever */ + VfsReq *req; + char tmp[64]; + size_t mlen = 0; + if (ring_used(r) == 0) return; + + /* read as much as the biggest request wants */ + for (req = *queue; req; req = req->postqueue_next) + mlen = max(mlen, req->output.len); + mlen = min(mlen, sizeof tmp); + mlen = ring_get(r, tmp, mlen); + + while (*queue) { + req = *queue; + *queue = req->postqueue_next; + req->postqueue_next = NULL; + + size_t ret = min(mlen, req->output.len); + assert(req->type == VFSOP_READ); + if (req->caller) { + pcpy_to(req->caller, req->output.buf, tmp, ret); + } + vfsreq_finish_short(req, ret); + } +} diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index 06c46e7..616c044 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -1,5 +1,6 @@ #pragma once #include <kernel/types.h> +#include <shared/ring.h> #include <stdbool.h> #include <stddef.h> @@ -77,3 +78,14 @@ void vfsback_userdown(VfsBackend *); /** Decrements the "provider" reference count. */ void vfsback_provdown(VfsBackend *); + +struct ReqQueue { + VfsReq *head; +}; +void postqueue_init(ReqQueue *q); +void postqueue_join(ReqQueue *q, VfsReq *req); +VfsReq *postqueue_pop(ReqQueue *q); + +/** If there are any pending read requests, and the ring buffer isn't empty, fulfill them + * all with a single read. */ +void postqueue_ringreadall(ReqQueue *q, ring_t *r); |