vmmcache: sleep while waiting for ready pages

This commit is contained in:
Matheus
2024-06-27 22:08:01 -03:00
parent f1efe195bf
commit 7821eb61c1
+13 -5
View File
@@ -14,6 +14,7 @@ static page_t **table;
static thread_t *writerthread; static thread_t *writerthread;
static semaphore_t sync; static semaphore_t sync;
static eventheader_t syncevent; static eventheader_t syncevent;
static eventheader_t pagereadyevent;
size_t vmmcache_cachedpages; size_t vmmcache_cachedpages;
#define HOLD_LOCK() \ #define HOLD_LOCK() \
@@ -119,11 +120,15 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
if (newpage) if (newpage)
pmm_release(pmm_getpageaddress(newpage)); pmm_release(pmm_getpageaddress(newpage));
eventlistener_t listener;
EVENT_INITLISTENER(&listener);
EVENT_ATTACH(&listener, &pagereadyevent);
// wait for page to be ready // wait for page to be ready
while ((page->flags & (PAGE_FLAGS_READY | PAGE_FLAGS_ERROR)) == 0) { while ((page->flags & (PAGE_FLAGS_READY | PAGE_FLAGS_ERROR)) == 0)
arch_e9_puts("waiting for ready page\n"); EVENT_WAIT(&listener, 0);
sched_yield(); // TODO proper sleeping mechanism here
} EVENT_DETACHALL(&listener);
if (page->flags & PAGE_FLAGS_ERROR) { if (page->flags & PAGE_FLAGS_ERROR) {
// the thread handling the page in failed to read it, we should retry it and see whats up // the thread handling the page in failed to read it, we should retry it and see whats up
@@ -159,7 +164,7 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
RELEASE_LOCK(); RELEASE_LOCK();
int error = VOP_GETPAGE(vnode, offset, newpage); int error = VOP_GETPAGE(vnode, offset, newpage);
// TODO wake up the sleeping threads when implemented
if (error) { if (error) {
// an error happened with GETPAGE, remove the page from the cache, // an error happened with GETPAGE, remove the page from the cache,
// tell the sleeping threads that something happened and free the page // tell the sleeping threads that something happened and free the page
@@ -173,10 +178,12 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
RELEASE_LOCK(); RELEASE_LOCK();
pmm_release(pmm_getpageaddress(newpage)); pmm_release(pmm_getpageaddress(newpage));
EVENT_SIGNAL(&pagereadyevent);
return error; return error;
} }
newpage->flags |= PAGE_FLAGS_READY; newpage->flags |= PAGE_FLAGS_READY;
EVENT_SIGNAL(&pagereadyevent);
*res = newpage; *res = newpage;
} }
@@ -421,4 +428,5 @@ void vmmcache_init() {
sched_queue(writerthread); sched_queue(writerthread);
vmmcache_sync(); vmmcache_sync();
EVENT_INITHEADER(&syncevent); EVENT_INITHEADER(&syncevent);
EVENT_INITHEADER(&pagereadyevent);
} }