mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
@@ -119,7 +119,6 @@ typedef struct vnode_t {
|
|||||||
void *fifobinding;
|
void *fifobinding;
|
||||||
};
|
};
|
||||||
|
|
||||||
mutex_t pages_mutex;
|
|
||||||
struct page_t *pages;
|
struct page_t *pages;
|
||||||
|
|
||||||
mutex_t adv_mutex;
|
mutex_t adv_mutex;
|
||||||
@@ -183,7 +182,6 @@ typedef struct vops_t {
|
|||||||
(vn)->ops = o; \
|
(vn)->ops = o; \
|
||||||
MUTEX_INIT(&(vn)->lock); \
|
MUTEX_INIT(&(vn)->lock); \
|
||||||
MUTEX_INIT(&(vn)->size_lock); \
|
MUTEX_INIT(&(vn)->size_lock); \
|
||||||
MUTEX_INIT(&(vn)->pages_mutex); \
|
|
||||||
MUTEX_INIT(&(vn)->adv_mutex); \
|
MUTEX_INIT(&(vn)->adv_mutex); \
|
||||||
(vn)->advlock = NULL; \
|
(vn)->advlock = NULL; \
|
||||||
(vn)->refcount = 1; \
|
(vn)->refcount = 1; \
|
||||||
|
|||||||
+46
-64
@@ -9,7 +9,7 @@
|
|||||||
#define TABLE_SIZE 4096
|
#define TABLE_SIZE 4096
|
||||||
#define WRITER_TICK_SECONDS 15
|
#define WRITER_TICK_SECONDS 15
|
||||||
|
|
||||||
static mutex_t *mutex_table;
|
static mutex_t mutex;
|
||||||
static page_t **table;
|
static page_t **table;
|
||||||
|
|
||||||
static thread_t *writerthread;
|
static thread_t *writerthread;
|
||||||
@@ -18,11 +18,11 @@ static eventheader_t syncevent;
|
|||||||
static eventheader_t pagereadyevent;
|
static eventheader_t pagereadyevent;
|
||||||
size_t vmmcache_cachedpages;
|
size_t vmmcache_cachedpages;
|
||||||
|
|
||||||
#define HOLD_LOCK(vnode, offset) \
|
#define HOLD_LOCK() \
|
||||||
MUTEX_ACQUIRE(&mutex_table[getentry(vnode, offset)]);
|
MUTEX_ACQUIRE(&mutex);
|
||||||
|
|
||||||
#define RELEASE_LOCK(vnode, offset) \
|
#define RELEASE_LOCK() \
|
||||||
MUTEX_RELEASE(&mutex_table[getentry(vnode, offset)]);
|
MUTEX_RELEASE(&mutex);
|
||||||
|
|
||||||
static inline uint64_t fnv1ahash(void *buffer, size_t size);
|
static inline uint64_t fnv1ahash(void *buffer, size_t size);
|
||||||
static uintmax_t getentry(vnode_t *vnode, uintmax_t offset) {
|
static uintmax_t getentry(vnode_t *vnode, uintmax_t offset) {
|
||||||
@@ -70,7 +70,7 @@ static void putpage(page_t *page) {
|
|||||||
page->backing->pages->vnodeprev = page;
|
page->backing->pages->vnodeprev = page;
|
||||||
|
|
||||||
page->backing->pages = page;
|
page->backing->pages = page;
|
||||||
__atomic_fetch_add(&vmmcache_cachedpages, 1, __ATOMIC_SEQ_CST);
|
++vmmcache_cachedpages;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assumes lock is held
|
// assumes lock is held
|
||||||
@@ -100,14 +100,14 @@ static void removepage(page_t *page) {
|
|||||||
|
|
||||||
page->vnodenext = NULL;
|
page->vnodenext = NULL;
|
||||||
page->vnodeprev = NULL;
|
page->vnodeprev = NULL;
|
||||||
__atomic_fetch_sub(&vmmcache_cachedpages, 1, __ATOMIC_SEQ_CST);
|
--vmmcache_cachedpages;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
||||||
__assert(vnode->type == V_TYPE_REGULAR || vnode->type == V_TYPE_BLKDEV);
|
__assert(vnode->type == V_TYPE_REGULAR || vnode->type == V_TYPE_BLKDEV);
|
||||||
__assert((offset % PAGE_SIZE) == 0);
|
__assert((offset % PAGE_SIZE) == 0);
|
||||||
retry_err:
|
retry_err:
|
||||||
HOLD_LOCK(vnode, offset);
|
HOLD_LOCK();
|
||||||
|
|
||||||
page_t *newpage = NULL;
|
page_t *newpage = NULL;
|
||||||
volatile page_t *page = findpage(vnode, offset);
|
volatile page_t *page = findpage(vnode, offset);
|
||||||
@@ -115,7 +115,7 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
|||||||
if (page) {
|
if (page) {
|
||||||
// page is present in the page cache
|
// page is present in the page cache
|
||||||
pmm_hold(pmm_getpageaddress((page_t *)page));
|
pmm_hold(pmm_getpageaddress((page_t *)page));
|
||||||
RELEASE_LOCK(vnode, offset);
|
RELEASE_LOCK();
|
||||||
|
|
||||||
// in the case of a retry, release the allocated page here
|
// in the case of a retry, release the allocated page here
|
||||||
if (newpage)
|
if (newpage)
|
||||||
@@ -140,7 +140,7 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
|||||||
*res = (page_t *)page;
|
*res = (page_t *)page;
|
||||||
} else {
|
} else {
|
||||||
// page is not present in the cache, we will have to load it in
|
// page is not present in the cache, we will have to load it in
|
||||||
RELEASE_LOCK(vnode, offset);
|
RELEASE_LOCK();
|
||||||
|
|
||||||
void *address = pmm_allocpage(PMM_SECTION_DEFAULT);
|
void *address = pmm_allocpage(PMM_SECTION_DEFAULT);
|
||||||
if (address == NULL)
|
if (address == NULL)
|
||||||
@@ -148,16 +148,13 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
|||||||
|
|
||||||
newpage = pmm_getpage(address);
|
newpage = pmm_getpage(address);
|
||||||
|
|
||||||
MUTEX_ACQUIRE(&vnode->pages_mutex);
|
HOLD_LOCK();
|
||||||
HOLD_LOCK(vnode, offset);
|
|
||||||
|
|
||||||
// while the lock wasn't being held, the page could have potentially been added to the cache
|
// while the lock wasn't being held, the page could have potentially been added to the cache
|
||||||
// check for it again and return from the function as if it was always there in the first place
|
// check for it again and return from the function as if it was always there in the first place
|
||||||
page = findpage(vnode, offset);
|
page = findpage(vnode, offset);
|
||||||
if (page) {
|
if (page)
|
||||||
MUTEX_RELEASE(&vnode->pages_mutex);
|
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
|
||||||
|
|
||||||
newpage->backing = vnode;
|
newpage->backing = vnode;
|
||||||
newpage->offset = offset;
|
newpage->offset = offset;
|
||||||
@@ -165,8 +162,7 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
|||||||
// add it to the page cache
|
// add it to the page cache
|
||||||
putpage(newpage);
|
putpage(newpage);
|
||||||
|
|
||||||
MUTEX_RELEASE(&vnode->pages_mutex);
|
RELEASE_LOCK();
|
||||||
RELEASE_LOCK(vnode, offset);
|
|
||||||
|
|
||||||
VOP_LOCK(vnode);
|
VOP_LOCK(vnode);
|
||||||
int error = VOP_GETPAGE(vnode, offset, newpage);
|
int error = VOP_GETPAGE(vnode, offset, newpage);
|
||||||
@@ -176,16 +172,14 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
|||||||
// 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
|
||||||
// by setting backing to null so it gets treated as an anonymous page again
|
// by setting backing to null so it gets treated as an anonymous page again
|
||||||
MUTEX_ACQUIRE(&vnode->pages_mutex);
|
HOLD_LOCK();
|
||||||
HOLD_LOCK(vnode, offset);
|
|
||||||
removepage(newpage);
|
removepage(newpage);
|
||||||
MUTEX_RELEASE(&vnode->pages_mutex);
|
|
||||||
|
|
||||||
newpage->flags |= PAGE_FLAGS_ERROR;
|
newpage->flags |= PAGE_FLAGS_ERROR;
|
||||||
newpage->backing = NULL;
|
newpage->backing = NULL;
|
||||||
newpage->offset = 0;
|
newpage->offset = 0;
|
||||||
|
|
||||||
RELEASE_LOCK(vnode, offset);
|
RELEASE_LOCK();
|
||||||
pmm_release(pmm_getpageaddress(newpage));
|
pmm_release(pmm_getpageaddress(newpage));
|
||||||
EVENT_SIGNAL(&pagereadyevent);
|
EVENT_SIGNAL(&pagereadyevent);
|
||||||
return error;
|
return error;
|
||||||
@@ -202,13 +196,11 @@ int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
|||||||
// adds a page to the cache in a specific offset if its not already there
|
// adds a page to the cache in a specific offset if its not already there
|
||||||
int vmmcache_pushpage(vnode_t *vnode, uintmax_t offset, page_t *page) {
|
int vmmcache_pushpage(vnode_t *vnode, uintmax_t offset, page_t *page) {
|
||||||
__assert((offset % PAGE_SIZE) == 0);
|
__assert((offset % PAGE_SIZE) == 0);
|
||||||
MUTEX_ACQUIRE(&vnode->pages_mutex);
|
HOLD_LOCK();
|
||||||
HOLD_LOCK(vnode, offset);
|
|
||||||
|
|
||||||
page_t *pagetest = findpage(vnode, offset);
|
page_t *pagetest = findpage(vnode, offset);
|
||||||
if (pagetest) {
|
if (pagetest) {
|
||||||
MUTEX_RELEASE(&vnode->pages_mutex);
|
RELEASE_LOCK();
|
||||||
RELEASE_LOCK(vnode, offset);
|
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,18 +210,15 @@ int vmmcache_pushpage(vnode_t *vnode, uintmax_t offset, page_t *page) {
|
|||||||
|
|
||||||
putpage(page);
|
putpage(page);
|
||||||
|
|
||||||
MUTEX_RELEASE(&vnode->pages_mutex);
|
RELEASE_LOCK();
|
||||||
RELEASE_LOCK(vnode, offset);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes a page from the cache AND turns it into anonymous memory
|
// removes a page from the cache AND turns it into anonymous memory
|
||||||
int vmmcache_evict(page_t *page) {
|
int vmmcache_evict(page_t *page) {
|
||||||
MUTEX_ACQUIRE(&page->backing->pages_mutex);
|
HOLD_LOCK();
|
||||||
HOLD_LOCK(page->backing, page->offset);
|
|
||||||
if (page->refcount > 1) {
|
if (page->refcount > 1) {
|
||||||
MUTEX_RELEASE(&page->backing->pages_mutex);
|
RELEASE_LOCK();
|
||||||
RELEASE_LOCK(page->backing, page->offset);
|
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
__assert(page->refcount == 1);
|
__assert(page->refcount == 1);
|
||||||
@@ -240,24 +229,21 @@ int vmmcache_evict(page_t *page) {
|
|||||||
removepage(page);
|
removepage(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_RELEASE(&page->backing->pages_mutex);
|
|
||||||
RELEASE_LOCK(page->backing, page->offset);
|
|
||||||
|
|
||||||
page->flags = 0;
|
page->flags = 0;
|
||||||
page->backing = NULL;
|
page->backing = NULL;
|
||||||
page->offset = 0;
|
page->offset = 0;
|
||||||
|
|
||||||
|
RELEASE_LOCK();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes a page from the cache *but doesn't do anything to it*
|
// removes a page from the cache *but doesn't do anything to it*
|
||||||
int vmmcache_takepage(page_t *page) {
|
int vmmcache_takepage(page_t *page) {
|
||||||
MUTEX_ACQUIRE(&page->backing->pages_mutex);
|
HOLD_LOCK();
|
||||||
HOLD_LOCK(page->backing, page->offset);
|
|
||||||
// someone called vmmcache_getpage() and got this page while the lock wasn't held
|
// someone called vmmcache_getpage() and got this page while the lock wasn't held
|
||||||
// return an error status to the caller
|
// return an error status to the caller
|
||||||
if (page->refcount > 1) {
|
if (page->refcount > 1) {
|
||||||
MUTEX_RELEASE(&page->backing->pages_mutex);
|
RELEASE_LOCK();
|
||||||
RELEASE_LOCK(page->backing, page->offset);
|
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,13 +256,12 @@ int vmmcache_takepage(page_t *page) {
|
|||||||
removepage(page);
|
removepage(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_RELEASE(&page->backing->pages_mutex);
|
RELEASE_LOCK();
|
||||||
RELEASE_LOCK(page->backing, page->offset);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vmmcache_truncate(vnode_t *vnode, uintmax_t offset) {
|
int vmmcache_truncate(vnode_t *vnode, uintmax_t offset) {
|
||||||
MUTEX_ACQUIRE(&vnode->pages_mutex);
|
HOLD_LOCK();
|
||||||
page_t *pagelist = NULL;
|
page_t *pagelist = NULL;
|
||||||
page_t *page = vnode->pages;
|
page_t *page = vnode->pages;
|
||||||
|
|
||||||
@@ -288,16 +273,13 @@ int vmmcache_truncate(vnode_t *vnode, uintmax_t offset) {
|
|||||||
if (oldpage->offset < offset)
|
if (oldpage->offset < offset)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
__atomic_or_fetch(&oldpage->flags, PAGE_FLAGS_TRUNCATED, __ATOMIC_SEQ_CST);
|
oldpage->flags |= PAGE_FLAGS_TRUNCATED;
|
||||||
HOLD_LOCK(oldpage->backing, oldpage->offset);
|
|
||||||
removepage(oldpage);
|
removepage(oldpage);
|
||||||
RELEASE_LOCK(oldpage->backing, oldpage->offset);
|
|
||||||
|
|
||||||
oldpage->vnodenext = pagelist;
|
oldpage->vnodenext = pagelist;
|
||||||
pagelist = oldpage;
|
pagelist = oldpage;
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_RELEASE(&vnode->pages_mutex);
|
RELEASE_LOCK();
|
||||||
|
|
||||||
// make sure to unref if they are pinned
|
// make sure to unref if they are pinned
|
||||||
while (pagelist) {
|
while (pagelist) {
|
||||||
@@ -310,11 +292,15 @@ int vmmcache_truncate(vnode_t *vnode, uintmax_t offset) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// called with lock held
|
||||||
|
// returns with lock released
|
||||||
|
// expects backing lock to be held
|
||||||
static int syncpage(page_t *page, bool backinglock) {
|
static int syncpage(page_t *page, bool backinglock) {
|
||||||
int flags = __atomic_fetch_and(&page->flags, ~PAGE_FLAGS_DIRTY, __ATOMIC_SEQ_CST);
|
__assert(page->flags & PAGE_FLAGS_DIRTY);
|
||||||
__assert(flags & PAGE_FLAGS_DIRTY);
|
page->flags &= ~PAGE_FLAGS_DIRTY;
|
||||||
|
RELEASE_LOCK();
|
||||||
int e = 0;
|
int e = 0;
|
||||||
if ((flags & PAGE_FLAGS_TRUNCATED) == 0) {
|
if ((page->flags & PAGE_FLAGS_TRUNCATED) == 0) {
|
||||||
if (backinglock)
|
if (backinglock)
|
||||||
VOP_LOCK(page->backing);
|
VOP_LOCK(page->backing);
|
||||||
|
|
||||||
@@ -333,7 +319,6 @@ static int syncpage(page_t *page, bool backinglock) {
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_DEFINE(dirty_list_mutex);
|
|
||||||
static page_t *dirtylist;
|
static page_t *dirtylist;
|
||||||
static page_t *dirtylistend;
|
static page_t *dirtylistend;
|
||||||
|
|
||||||
@@ -343,8 +328,7 @@ int vmmcache_syncvnode(vnode_t *vnode, uintmax_t offset, size_t size) {
|
|||||||
uintmax_t top = offset + size;
|
uintmax_t top = offset + size;
|
||||||
// overflow check
|
// overflow check
|
||||||
__assert(top > offset);
|
__assert(top > offset);
|
||||||
MUTEX_ACQUIRE(&vnode->pages_mutex);
|
HOLD_LOCK();
|
||||||
MUTEX_ACQUIRE(&dirty_list_mutex);
|
|
||||||
|
|
||||||
// loop through all vnode pages in memory and check which ones are in the range and are dirty
|
// loop through all vnode pages in memory and check which ones are in the range and are dirty
|
||||||
// TODO create a proper vnode dirty list as to not have to loop through the ENTIRE thing in memory
|
// TODO create a proper vnode dirty list as to not have to loop through the ENTIRE thing in memory
|
||||||
@@ -372,13 +356,13 @@ int vmmcache_syncvnode(vnode_t *vnode, uintmax_t offset, size_t size) {
|
|||||||
vnodedirtylist = page;
|
vnodedirtylist = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_RELEASE(&dirty_list_mutex);
|
RELEASE_LOCK();
|
||||||
MUTEX_RELEASE(&vnode->pages_mutex);
|
|
||||||
|
|
||||||
int e = 0;
|
int e = 0;
|
||||||
while (vnodedirtylist) {
|
while (vnodedirtylist) {
|
||||||
// in the case of failure, only the first error to occur will be reported and we will not
|
// in the case of failure, only the first error to occur will be reported and we will not
|
||||||
// retry the write and keep on syncing the pages to disk
|
// retry the write and keep on syncing the pages to disk
|
||||||
|
HOLD_LOCK();
|
||||||
page_t *page = vnodedirtylist;
|
page_t *page = vnodedirtylist;
|
||||||
vnodedirtylist = vnodedirtylist->writenext;
|
vnodedirtylist = vnodedirtylist->writenext;
|
||||||
page->writenext = NULL;
|
page->writenext = NULL;
|
||||||
@@ -396,13 +380,16 @@ int vmmcache_syncvnode(vnode_t *vnode, uintmax_t offset, size_t size) {
|
|||||||
int vmmcache_sync() {
|
int vmmcache_sync() {
|
||||||
eventlistener_t eventlistener;
|
eventlistener_t eventlistener;
|
||||||
EVENT_INITLISTENER(&eventlistener);
|
EVENT_INITLISTENER(&eventlistener);
|
||||||
|
HOLD_LOCK();
|
||||||
if (dirtylist == NULL) {
|
if (dirtylist == NULL) {
|
||||||
// no dirty pages
|
// no dirty pages
|
||||||
|
RELEASE_LOCK();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVENT_ATTACH(&eventlistener, &syncevent);
|
EVENT_ATTACH(&eventlistener, &syncevent);
|
||||||
semaphore_signal(&sync);
|
semaphore_signal(&sync);
|
||||||
|
RELEASE_LOCK();
|
||||||
|
|
||||||
EVENT_WAIT(&eventlistener, 0);
|
EVENT_WAIT(&eventlistener, 0);
|
||||||
|
|
||||||
@@ -413,7 +400,7 @@ int vmmcache_sync() {
|
|||||||
// backing expected locked
|
// backing expected locked
|
||||||
int vmmcache_makedirty(page_t *page) {
|
int vmmcache_makedirty(page_t *page) {
|
||||||
bool madedirty = false;
|
bool madedirty = false;
|
||||||
MUTEX_ACQUIRE(&dirty_list_mutex);
|
HOLD_LOCK();
|
||||||
|
|
||||||
if ((page->flags & (PAGE_FLAGS_DIRTY | PAGE_FLAGS_TRUNCATED)) == 0) {
|
if ((page->flags & (PAGE_FLAGS_DIRTY | PAGE_FLAGS_TRUNCATED)) == 0) {
|
||||||
madedirty = true;
|
madedirty = true;
|
||||||
@@ -433,7 +420,7 @@ int vmmcache_makedirty(page_t *page) {
|
|||||||
VOP_HOLD(page->backing);
|
VOP_HOLD(page->backing);
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_RELEASE(&dirty_list_mutex);
|
RELEASE_LOCK();
|
||||||
if (madedirty) {
|
if (madedirty) {
|
||||||
vattr_t attr;
|
vattr_t attr;
|
||||||
attr.mtime = timekeeper_time();
|
attr.mtime = timekeeper_time();
|
||||||
@@ -453,11 +440,11 @@ static void writer() {
|
|||||||
timer_insert(current_cpu()->timer, &timerentry, tick, NULL, (uintmax_t)WRITER_TICK_SECONDS * 1000000, true);
|
timer_insert(current_cpu()->timer, &timerentry, tick, NULL, (uintmax_t)WRITER_TICK_SECONDS * 1000000, true);
|
||||||
interrupt_set(true);
|
interrupt_set(true);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
MUTEX_ACQUIRE(&dirty_list_mutex);
|
HOLD_LOCK();
|
||||||
volatile page_t *page = dirtylistend;
|
volatile page_t *page = dirtylistend;
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
MUTEX_RELEASE(&dirty_list_mutex);
|
|
||||||
EVENT_SIGNAL(&syncevent);
|
EVENT_SIGNAL(&syncevent);
|
||||||
|
RELEASE_LOCK();
|
||||||
semaphore_wait(&sync, false);
|
semaphore_wait(&sync, false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -469,21 +456,16 @@ static void writer() {
|
|||||||
dirtylist = NULL;
|
dirtylist = NULL;
|
||||||
|
|
||||||
page->writeprev = NULL;
|
page->writeprev = NULL;
|
||||||
MUTEX_RELEASE(&dirty_list_mutex);
|
|
||||||
|
|
||||||
// TODO notify error on vmmcache_syncvnode
|
// TODO notify error on vmmcache_syncvnode
|
||||||
syncpage((page_t *)page, true);
|
syncpage((page_t *)page, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmmcache_init() {
|
void vmmcache_init() {
|
||||||
|
MUTEX_INIT(&mutex);
|
||||||
table = vmm_map(NULL, TABLE_SIZE * sizeof(page_t *), VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
table = vmm_map(NULL, TABLE_SIZE * sizeof(page_t *), VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||||
__assert(table);
|
__assert(table);
|
||||||
mutex_table = vmm_map(NULL, TABLE_SIZE * sizeof(mutex_t), VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
|
||||||
__assert(mutex_table);
|
|
||||||
memset(table, 0, TABLE_SIZE * sizeof(page_t *));
|
memset(table, 0, TABLE_SIZE * sizeof(page_t *));
|
||||||
for (int i = 0; i < TABLE_SIZE; ++i)
|
|
||||||
MUTEX_INIT(&mutex_table[i]);
|
|
||||||
|
|
||||||
SEMAPHORE_INIT(&sync, 0);
|
SEMAPHORE_INIT(&sync, 0);
|
||||||
writerthread = sched_newthread(writer, PAGE_SIZE * 16, 1, NULL, NULL);
|
writerthread = sched_newthread(writer, PAGE_SIZE * 16, 1, NULL, NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user