提交 7dd0fbb3 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

preparing to merge vma and range

上级 aa6ff8df
......@@ -5,7 +5,9 @@
using std::atomic;
struct crange;
struct crange_locked;
struct range;
class range_iterator;
template<class T>
class markptr_ptr;
......@@ -83,25 +85,35 @@ class markptr_mark : public markptr<T> {
};
struct range : public rcu_freed {
public:
private:
u64 key;
u64 size;
public:
rcu_freed *value;
private:
atomic<int> curlevel; // the current levels it appears on
int nlevel; // the number of levels this range should appear
crange *cr; // the crange this range is part of
markptr<range>* next; // one next pointer per level
spinlock *lock; // on separate cache line?
range(crange *cr, u64 k, u64 sz, rcu_freed *v, range *n, int nlevel = 0);
void print(int l);
void dec_ref(void);
int lockif(markptr<range> e);
~range();
friend class crange;
friend class crange_locked;
friend class range_iterator;
public:
range(crange *cr, u64 k, u64 sz, rcu_freed *v, range *n, int nlevel = 0);
virtual void do_gc() {
delete this;
}
void print(int l);
void dec_ref(void);
int lockif(markptr<range> e);
} __mpalign__;
class range_iterator {
......@@ -123,11 +135,17 @@ struct crange {
private:
range *crange_head; // a crange skip list starts with a sentinel range (key 0, sz 0)
static void mark(range *f, range *s);
static void freen(struct range *f, struct range *l);
static int lock_range(u64 k, u64 sz, int l, range **er, range **pr, range **fr, range **lr, range **sr);
void print(int);
void check(struct range *absent);
int del_index(range *p0, range **e, int l);
void add_index(int l, range *e, range *p1, markptr<range> s1);
int find_and_lock(u64 k, u64 sz, range **p0, range **f0, range **l0, range **s0);
friend class crange_locked;
friend class range;
public:
......
......@@ -161,8 +161,8 @@ range::lockif(markptr<range> e)
// causing curlevel to drop below nlevel, and causing add_index to add the
// node back on level on which it already has been inserted (because it hasn't
// been marked deleted yet at that level).
static void
mark(range *f, range *s)
void
crange::mark(range *f, range *s)
{
struct range *e;
for (e = f; e && e != s; e = e->next[0].ptr()) {
......@@ -173,8 +173,8 @@ mark(range *f, range *s)
}
// Delay free ranges f through l
static void
freen(struct range *f, struct range *l)
void
crange::freen(struct range *f, struct range *l)
{
struct range *e;
for (e = f; e && e != l; e = e->next[0].ptr()) {
......@@ -220,7 +220,7 @@ crange::~crange()
range *e, *n;
for (e = crange_head->next[0].ptr(); e; e = n) {
n = e->next[0].ptr();
delete e;
e->do_gc();
}
delete crange_head;
}
......@@ -342,8 +342,8 @@ crange::add_index(int l, range *e, range *p1, markptr<range> s1)
// Given the range that starts the sequence, find all other ranges part of sequence and lock them,
// if l == 0
static int
lock_range(u64 k, u64 sz, int l, range **er, range **pr, range **fr, range **lr, range **sr)
int
crange::lock_range(u64 k, u64 sz, int l, range **er, range **pr, range **fr, range **lr, range **sr)
{
struct range *e = *er;
assert(*pr != e);
......@@ -525,11 +525,11 @@ crange_locked::replace(range *repl)
// do compare-exchange first, and only then mark the old ranges as deleted;
// otherwise, concurrent readers may not find either old or new ranges.
assert(prev_->next[0].cmpxch(first_?:succ_, repl?:succ_));
mark(first_, succ_);
crange::mark(first_, succ_);
for (range *e = first_; e && e != succ_; e = e->next[0].ptr())
release(e->lock);
freen(first_, last_);
crange::freen(first_, last_);
first_ = repl;
last_ = newlast;
......
......@@ -282,7 +282,8 @@ vmap::insert(vmnode *n, uptr vma_start)
u64 len = n->npages * PGSIZE;
auto span = cr.search_lock(vma_start, len);
for (auto r: span) {
cprintf("vmap::insert: overlap 0x%lx @ 0x%lx\n", r->size, r->key);
vma *rvma = (vma*) r->value;
cprintf("vmap::insert: overlap with 0x%lx--0x%lx\n", rvma->vma_start, rvma->vma_end);
return -1;
}
......@@ -323,7 +324,8 @@ vmap::remove(uptr vma_start, uptr len)
auto span = cr.search_lock(vma_start, len);
for (auto r: span) {
if (r->key < vma_start || r->key + r->size > vma_end) {
vma *rvma = (vma*) r->value;
if (rvma->vma_start < vma_start || rvma->vma_end > vma_end) {
cprintf("vmap::remove: partial unmap not supported\n");
return -1;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论