diff options
Diffstat (limited to 'user')
| -rw-r--r-- | user/cow.c | 144 | 
1 files changed, 143 insertions, 1 deletions
| @@ -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();  } | 
