diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2019-07-02 11:04:35 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2019-07-02 11:04:35 -0400 | 
| commit | 1540c8b15ac35de9027e60804a786d23703d383d (patch) | |
| tree | b30d9dd51717a08851b99d0cc118009e219ec93d | |
| parent | 40f1041a0a7cd8a1902371cf459989c19f1dc718 (diff) | |
| download | xv6-labs-1540c8b15ac35de9027e60804a786d23703d383d.tar.gz xv6-labs-1540c8b15ac35de9027e60804a786d23703d383d.tar.bz2 xv6-labs-1540c8b15ac35de9027e60804a786d23703d383d.zip | |
COW tests
| -rw-r--r-- | kernel/vm.c | 2 | ||||
| -rw-r--r-- | user/cow.c | 144 | 
2 files changed, 144 insertions, 2 deletions
| diff --git a/kernel/vm.c b/kernel/vm.c index 7d67464..d5ff594 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -97,8 +97,8 @@ walk(pagetable_t pagetable, uint64 va, int alloc)  }  // Look up a virtual address, return the physical address, -// Can only be used to look up user pages.  // or 0 if not mapped. +// Can only be used to look up user pages.  uint64  walkaddr(pagetable_t pagetable, uint64 va)  { @@ -43,12 +43,154 @@ simpletest()      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  main(int argc, char *argv[])  {    simpletest(); + +  // check that the first simpletest() freed the physical memory. +  simpletest(); + +  threetest(); +  threetest(); +  threetest(); + +  filetest(); + +  printf(1, "ALL COW TESTS PASSED\n"); +    exit();  } | 
