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