COW tests
This commit is contained in:
parent
40f1041a0a
commit
1540c8b15a
|
@ -97,8 +97,8 @@ walk(pagetable_t pagetable, uint64 va, int alloc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up a virtual address, return the physical address,
|
// Look up a virtual address, return the physical address,
|
||||||
// Can only be used to look up user pages.
|
|
||||||
// or 0 if not mapped.
|
// or 0 if not mapped.
|
||||||
|
// Can only be used to look up user pages.
|
||||||
uint64
|
uint64
|
||||||
walkaddr(pagetable_t pagetable, uint64 va)
|
walkaddr(pagetable_t pagetable, uint64 va)
|
||||||
{
|
{
|
||||||
|
|
144
user/cow.c
144
user/cow.c
|
@ -43,12 +43,154 @@ simpletest()
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(1, "simple ok\n");
|
printf(1, "ok\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// three processes all write COW memory.
|
||||||
|
// this causes more than half of physical memory
|
||||||
|
// to be allocated, so it also checks whether
|
||||||
|
// copied pages are freed.
|
||||||
|
void
|
||||||
|
threetest()
|
||||||
|
{
|
||||||
|
uint64 phys_size = PHYSTOP - KERNBASE;
|
||||||
|
int sz = phys_size / 4;
|
||||||
|
int pid1, pid2;
|
||||||
|
|
||||||
|
printf(1, "three: ");
|
||||||
|
|
||||||
|
char *p = sbrk(sz);
|
||||||
|
if(p == (char*)0xffffffffffffffffL){
|
||||||
|
printf(1, "sbrk(%d) failed\n", sz);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pid1 = fork();
|
||||||
|
if(pid1 < 0){
|
||||||
|
printf(1, "fork failed\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if(pid1 == 0){
|
||||||
|
pid2 = fork();
|
||||||
|
if(pid2 < 0){
|
||||||
|
printf(1, "fork failed");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if(pid2 == 0){
|
||||||
|
for(char *q = p; q < p + (sz/5)*4; q += 4096){
|
||||||
|
*(int*)q = getpid();
|
||||||
|
}
|
||||||
|
for(char *q = p; q < p + (sz/5)*4; q += 4096){
|
||||||
|
if(*(int*)q != getpid()){
|
||||||
|
printf(1, "wrong content\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
for(char *q = p; q < p + (sz/2); q += 4096){
|
||||||
|
*(int*)q = 9999;
|
||||||
|
}
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(char *q = p; q < p + sz; q += 4096){
|
||||||
|
*(int*)q = getpid();
|
||||||
|
}
|
||||||
|
|
||||||
|
wait();
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
for(char *q = p; q < p + sz; q += 4096){
|
||||||
|
if(*(int*)q != getpid()){
|
||||||
|
printf(1, "wrong content\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sbrk(-sz) == (char*)0xffffffffffffffffL){
|
||||||
|
printf(1, "sbrk(-%d) failed\n", sz);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(1, "ok\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char junk1[4096];
|
||||||
|
int fds[2];
|
||||||
|
char junk2[4096];
|
||||||
|
char buf[4096];
|
||||||
|
char junk3[4096];
|
||||||
|
|
||||||
|
// test whether copyout() simulates COW faults.
|
||||||
|
void
|
||||||
|
filetest()
|
||||||
|
{
|
||||||
|
int parent = getpid();
|
||||||
|
|
||||||
|
printf(1, "file test: ");
|
||||||
|
|
||||||
|
buf[0] = 99;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
if(pipe(fds) != 0){
|
||||||
|
printf(1, "pipe() failed\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
int pid = fork();
|
||||||
|
if(pid < 0){
|
||||||
|
printf(1, "fork failed\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if(pid == 0){
|
||||||
|
sleep(1);
|
||||||
|
if(read(fds[0], buf, sizeof(i)) != sizeof(i)){
|
||||||
|
printf(1, "read failed\n");
|
||||||
|
kill(parent);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
int j = *(int*)buf;
|
||||||
|
if(j != i){
|
||||||
|
printf(1, "read the wrong value\n");
|
||||||
|
kill(parent);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if(write(fds[1], &i, sizeof(i)) != sizeof(i)){
|
||||||
|
printf(1, "write failed\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
wait();
|
||||||
|
|
||||||
|
if(buf[0] != 99){
|
||||||
|
printf(1, "child overwrote parent\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(1, "ok\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
simpletest();
|
simpletest();
|
||||||
|
|
||||||
|
// check that the first simpletest() freed the physical memory.
|
||||||
|
simpletest();
|
||||||
|
|
||||||
|
threetest();
|
||||||
|
threetest();
|
||||||
|
threetest();
|
||||||
|
|
||||||
|
filetest();
|
||||||
|
|
||||||
|
printf(1, "ALL COW TESTS PASSED\n");
|
||||||
|
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue