提交 a1477b27 创建 作者: Robert Morris's avatar Robert Morris

vma_overlap()

上级 eda2be67
......@@ -173,6 +173,7 @@ void vmn_free(struct vmnode *);
int vmn_load(struct vmnode *, struct inode*, uint, uint);
struct vmap * vmap_alloc(void);
void vmap_decref(struct vmap *);
int vmap_overlap(struct vmap *m, uint start, uint end);
int vmap_insert(struct vmap *, struct vmnode *n, uint);
int vmap_remove(struct vmap *, uint va_start, uint len);
struct vma * vmap_lookup(struct vmap *, uint);
......
......@@ -30,10 +30,9 @@ struct context {
};
enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
enum vmatype { PRIVATE, COW};
enum vmntype { EAGER, ONDEMAND};
// Virtual memory
// A memory object (physical pages or inode).
enum vmntype { EAGER, ONDEMAND};
struct vmnode {
uint npages;
char *page[32];
......@@ -45,6 +44,9 @@ struct vmnode {
uint sz;
};
// A mapping of a chunk of an address space to
// a specific memory object.
enum vmatype { PRIVATE, COW};
struct vma {
uint va_start; // start of mapping
uint va_end; // one past the last byte
......@@ -53,6 +55,8 @@ struct vma {
struct spinlock lock; // serialize fault/unmap
};
// An address space: a set of vmas plus h/w page table.
// The elements of e[] are not ordered by address.
struct vmap {
struct vma e[16];
struct spinlock lock; // serialize map/lookup/unmap
......
......@@ -384,25 +384,48 @@ vmap_decref(struct vmap *m)
vmap_free(m);
}
// Does any vma overlap start..start+len?
// If yes, return the m->e[] index.
// If no, return -1.
// This code can't handle regions at the very end
// of the address space, e.g. 0xffffffff..0x0
int
vmap_overlap(struct vmap *m, uint start, uint len)
{
if(holding(&m->lock) == 0)
panic("vmap_overlap no lock");
if(start + len < start)
panic("vmap_overlap bad len");
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++){
if(m->e[i].n){
if(m->e[i].va_end <= m->e[i].va_start)
panic("vmap_overlap bad vma");
if(m->e[i].va_start < start+len && m->e[i].va_end > start)
return i;
}
}
return -1;
}
int
vmap_insert(struct vmap *m, struct vmnode *n, uint va_start)
{
acquire(&m->lock);
uint va_end = va_start + n->npages * PGSIZE;
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) {
if(m->e[i].n && (m->e[i].va_start < va_end && m->e[i].va_end > va_start)) {
uint len = n->npages * PGSIZE;
if(vmap_overlap(m, va_start, len) != -1){
release(&m->lock);
cprintf("vmap_insert: overlap\n");
return -1;
}
}
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) {
if(m->e[i].n)
continue;
__sync_fetch_and_add(&n->ref, 1);
m->e[i].va_start = va_start;
m->e[i].va_end = va_end;
m->e[i].va_end = va_start + len;
m->e[i].n = n;
release(&m->lock);
return 0;
......@@ -438,14 +461,13 @@ struct vma *
vmap_lookup(struct vmap *m, uint va)
{
acquire(&m->lock);
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) {
struct vma *e = &m->e[i];
if (e->n && va >= e->va_start && va < e->va_end) {
int ind = vmap_overlap(m, va, 1);
if(ind >= 0){
struct vma *e = &m->e[ind];
acquire(&e->lock);
release(&m->lock);
return e;
}
}
release(&m->lock);
return 0;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论