提交 f510b21f 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

Use crange instead of bonsai

Runs the "benchmark" suite
上级 3587c3ec
......@@ -28,7 +28,6 @@ LDFLAGS += -m elf_x86_64
OBJS = \
bio.o \
bonsai.o \
cga.o \
condvar.o \
console.o \
......
差异被折叠。
......@@ -38,6 +38,7 @@ struct buf* bread(u32, u64, int writer);
void brelse(struct buf*, int writer);
void bwrite(struct buf*);
#if 0
// bonsai.c
struct kv {
u64 key;
......@@ -50,6 +51,7 @@ struct node* tree_insert(struct node *n, struct kv *kv);
struct node* tree_remove(struct node *n, u64 key);
int tree_foreach(struct node *n, int (*cb)(struct kv* kv, void *), void *);
void tree_test(void);
#endif
// cga.c
void cgaputc(int c);
......@@ -65,6 +67,28 @@ void panic(const char*) __attribute__((noreturn));
void snprintf(char *buf, u32 n, char *fmt, ...);
void consoleintr(int(*)(void));
// crange.c
struct clist_range {
u64 key;
u64 size;
void *value;
int curlevel;
int nlevel;
struct crange *cr;
struct clist_range** next; // one next pointer per level
struct spinlock *lock; // on separate cache line?
} __mpalign__;
struct crange;
struct crange* crange_init(int nlevel);
void crange_del(struct crange *cr, u64 k, u64 sz);
void crange_add(struct crange *cr, u64 k, u64 sz, void *v);
struct clist_range* crange_search(struct crange *cr, u64 k);
int crange_foreach(struct crange *crk, int (*f)(struct clist_range *r, void *st), void *st);
void crange_print(struct crange *cr, int);
// exec.c
int exec(char*, char**);
......
......@@ -565,7 +565,7 @@ fork(int flags)
struct proc *np;
int cow = 1;
// cprintf("%d: fork\n", proc->pid);
// cprintf("%d: fork\n", myproc()->pid);
// Allocate process.
if((np = allocproc()) == 0)
......
......@@ -13,6 +13,8 @@
static void vmap_free(void *p);
enum { vm_debug = 0 };
static struct vma *
vma_alloc(void)
{
......@@ -103,7 +105,6 @@ vmap_alloc(void)
struct vmap *m = kmalloc(sizeof(struct vmap));
if (m == 0)
return 0;
memset(m, 0, sizeof(struct vmap));
snprintf(m->lockname, sizeof(m->lockname), "vmap:%p", m);
initlock(&m->lock, m->lockname);
......@@ -114,6 +115,11 @@ vmap_alloc(void)
kmfree(m);
return 0;
}
#ifdef TREE
m->cr = crange_init(10);
if (m->cr == 0)
return 0;
#endif
return m;
}
......@@ -210,6 +216,9 @@ pagefault(struct vmap *vmap, uptr va, u32 err)
if (m->n && m->n->type == ONDEMAND && m->n->page[npg] == 0)
m = pagefault_ondemand(vmap, va, err, m);
if (vm_debug)
cprintf("pagefault: err 0x%x va 0x%x type %d ref %d pid %d\n", err, va, m->va_type, m->n->ref, myproc()->pid);
if (m->va_type == COW && (err & FEC_WR)) {
if (pagefault_wcow(vmap, va, pte, m, npg) < 0) {
release(&m->lock);
......@@ -301,15 +310,14 @@ vmn_alloc(u64 npg, enum vmntype type)
struct state {
int share;
void *pml4;
struct node *root;
struct crange *cr;
};
static int
vmap_free_vma(struct kv *kv, void *p)
vmap_free_vma(struct clist_range *r, void *st)
{
struct state *st = (struct state *) p;
vma_free(kv->val);
st->root = tree_remove(st->root, kv->key);
vma_free(r->value);
crange_del(r->cr, r->key, r->size);
return 1;
}
......@@ -317,12 +325,8 @@ static void
vmap_free(void *p)
{
struct vmap *m = (struct vmap *) p;
struct state *st = kmalloc(sizeof(struct state));
st->root = m->root;
tree_foreach(m->root, vmap_free_vma, st);
m->root = st->root;
crange_foreach(m->cr, vmap_free_vma, NULL);
freevm(m->pml4);
kmfree(st);
m->pml4 = 0;
m->alloc = 0;
}
......@@ -339,9 +343,9 @@ vmap_lookup(struct vmap *m, uptr start, uptr len)
if(start + len < start)
panic("vmap_lookup bad len");
struct kv *kv = tree_find_gt(m->root, start); // find vma with va_end > start
if (kv != 0) {
struct vma *e = (struct vma *) (kv->val);
struct clist_range *r = crange_search(m->cr, start);
if (r != 0) {
struct vma *e = (struct vma *) (r->value);
if (e->va_end <= e->va_start)
panic("malformed va");
if (e->va_start < start+len && e->va_end > start) {
......@@ -365,7 +369,6 @@ vmap_insert(struct vmap *m, struct vmnode *n, uptr va_start)
}
struct vma *e = vma_alloc();
struct kv kv;
if (e == 0) {
release(&m->lock);
return -1;
......@@ -374,18 +377,16 @@ vmap_insert(struct vmap *m, struct vmnode *n, uptr va_start)
e->va_end = va_start + len;
e->n = n;
__sync_fetch_and_add(&n->ref, 1);
kv.key = e->va_end;
kv.val = e;
m->root = tree_insert(m->root, &kv);
crange_add(m->cr, e->va_start, len, (void *) e);
release(&m->lock);
return 0;
}
static int
vmap_copy_vma(struct kv *kv, void *_st)
vmap_copy_vma(struct clist_range *r, void *_st)
{
struct state *st = (struct state *) _st;
struct vma *e = (struct vma *) kv->val;
struct vma *e = (struct vma *) r->value;
struct vma *c = vma_alloc();
if (c == 0) {
return 0;
......@@ -407,10 +408,7 @@ vmap_copy_vma(struct kv *kv, void *_st)
return 0;
}
__sync_fetch_and_add(&c->n->ref, 1);
struct kv kv1;
kv1.key = c->va_end;
kv1.val = (void *) c;
st->root = tree_insert(st->root, &kv1);
crange_add(st->cr, c->va_start, c->va_end - c->va_start, (void *) c);
return 1;
}
......@@ -425,14 +423,13 @@ vmap_copy(struct vmap *m, int share)
struct state *st = kmalloc(sizeof(struct state));
st->share = share;
st->pml4 = m->pml4;
st->root = c->root;
if (!tree_foreach(m->root, vmap_copy_vma, st)) {
st->cr = c->cr;
if (!crange_foreach(m->cr, vmap_copy_vma, st)) {
vmap_free(c);
release(&m->lock);
kmfree(st);
return 0;
}
c->root = st->root;
kmfree(st);
if (share)
......@@ -447,16 +444,16 @@ vmap_remove(struct vmap *m, uptr va_start, u64 len)
{
acquire(&m->lock);
uptr va_end = va_start + len;
struct kv *kv = tree_find_gt(m->root, va_start);
if (kv == 0)
struct clist_range *r = crange_search(m->cr, va_start);
if (r == 0)
panic("no vma?");
struct vma *e = (struct vma *) kv->val;
struct vma *e = (struct vma *) r->value;
if(e->va_start != va_start || e->va_end != va_end) {
cprintf("vmap_remove: partial unmap unsupported\n");
release(&m->lock);
return -1;
}
m->root = tree_remove(m->root, va_start+len);
crange_del(m->cr, va_start, len);
gc_delayed(e, vma_free);
release(&m->lock);
return 0;
......
......@@ -28,7 +28,8 @@ struct vmnode {
// The elements of e[] are not ordered by address.
struct vmap {
#ifdef TREE
struct node* root;
// struct node* root;
struct crange* cr;
#else
struct vma* e[16];
#endif
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论