cowtest fixed and try to finish usertests
This commit is contained in:
@@ -9,6 +9,12 @@
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
|
||||
#define NPAGE ((PHYSTOP - KERNBASE) / PGSIZE)
|
||||
static int refcnt[NPAGE];
|
||||
static inline int pa2idx(void *pa) {
|
||||
return ((uint64)pa - KERNBASE) / PGSIZE;
|
||||
}
|
||||
|
||||
void freerange(void *pa_start, void *pa_end);
|
||||
|
||||
extern char end[]; // first address after kernel.
|
||||
@@ -23,10 +29,25 @@ struct {
|
||||
struct run *freelist;
|
||||
} kmem;
|
||||
|
||||
void incref(void *pa) {
|
||||
int idx = pa2idx(pa);
|
||||
refcnt[idx]++;
|
||||
}
|
||||
void decref(void *pa) {
|
||||
int idx = pa2idx(pa);
|
||||
refcnt[idx]--;
|
||||
}
|
||||
int getref(void *pa) {
|
||||
int idx = pa2idx(pa);
|
||||
return refcnt[idx];
|
||||
}
|
||||
|
||||
void
|
||||
kinit()
|
||||
{
|
||||
initlock(&kmem.lock, "kmem");
|
||||
for(int i = 0; i < NPAGE; i++)
|
||||
refcnt[i] = 0;
|
||||
freerange(end, (void*)PHYSTOP);
|
||||
}
|
||||
|
||||
@@ -51,6 +72,16 @@ kfree(void *pa)
|
||||
if(((uint64)pa % PGSIZE) != 0 || (char*)pa < end || (uint64)pa >= PHYSTOP)
|
||||
panic("kfree");
|
||||
|
||||
int idx = pa2idx(pa);
|
||||
acquire(&kmem.lock);
|
||||
if(refcnt[idx] > 1) {
|
||||
refcnt[idx]--;
|
||||
release(&kmem.lock);
|
||||
return;
|
||||
}
|
||||
refcnt[idx] = 0;
|
||||
release(&kmem.lock);
|
||||
|
||||
// Fill with junk to catch dangling refs.
|
||||
memset(pa, 1, PGSIZE);
|
||||
|
||||
@@ -76,7 +107,10 @@ kalloc(void)
|
||||
kmem.freelist = r->next;
|
||||
release(&kmem.lock);
|
||||
|
||||
if(r)
|
||||
if(r) {
|
||||
memset((char*)r, 5, PGSIZE); // fill with junk
|
||||
int idx = pa2idx((void*)r);
|
||||
refcnt[idx] = 1;
|
||||
}
|
||||
return (void*)r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user