lib: Add epoch-based SMR
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: ISC
|
||||
|
||||
#include <zinnia/alloc.h>
|
||||
#include <zinnia/epoch.h>
|
||||
#include <zinnia/errno.h>
|
||||
#include <zinnia/print.h>
|
||||
#include <zinnia/utils.h>
|
||||
@@ -143,10 +144,34 @@ static errno_t fill(struct vmo* vmo, uint64_t index, enum vmo_access access, str
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct page* lookup_fast(struct vmo* vmo, uint64_t index) {
|
||||
epoch_enter();
|
||||
struct page* page = radix_lookup(&vmo->pages, index);
|
||||
if (page && !page_try_hold(page))
|
||||
page = nullptr;
|
||||
const bool valid =
|
||||
page && radix_lookup(&vmo->pages, index) == page && !(atomic_load(&page->flags, ATOMIC_ACQUIRE) & PAGE_BUSY);
|
||||
epoch_exit();
|
||||
|
||||
if (page && !valid) {
|
||||
page_unhold(page);
|
||||
return nullptr;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
errno_t vmo_get_page(struct vmo* vmo, uint64_t index, enum vmo_access access, struct page** out) {
|
||||
if (vmo->pager->lookup)
|
||||
return ENOTSUP;
|
||||
|
||||
if (access == VMO_READ) {
|
||||
struct page* page = lookup_fast(vmo, index);
|
||||
if (page) {
|
||||
*out = page;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&vmo->lock);
|
||||
while (true) {
|
||||
struct page* page = radix_lookup(&vmo->pages, index);
|
||||
|
||||
Reference in New Issue
Block a user