diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2020-08-27 06:21:10 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2020-08-27 06:21:10 -0400 | 
| commit | d7e5f269106f4b76fcbd90331a3b44f879ee9c54 (patch) | |
| tree | 1e46fc4ae3dc2d00b8bb7a703818bc81e6cd6f06 | |
| parent | efaa7b8e2ae2ae059f3985bda718d91f3501b294 (diff) | |
| download | xv6-labs-d7e5f269106f4b76fcbd90331a3b44f879ee9c54.tar.gz xv6-labs-d7e5f269106f4b76fcbd90331a3b44f879ee9c54.tar.bz2 xv6-labs-d7e5f269106f4b76fcbd90331a3b44f879ee9c54.zip | |
fix usertests to pass all the riscv-sol-fall20 solutions.
| -rw-r--r-- | user/usertests.c | 119 | 
1 files changed, 97 insertions, 22 deletions
| diff --git a/user/usertests.c b/user/usertests.c index 502621a..db042e6 100644 --- a/user/usertests.c +++ b/user/usertests.c @@ -997,6 +997,11 @@ mem(char *s)    } else {      int xstatus;      wait(&xstatus); +    if(xstatus == -1){ +      // probably page fault, so might be lazy lab, +      // so OK. +      exit(0); +    }      exit(xstatus);    }  } @@ -1955,9 +1960,31 @@ sbrkbasic(char *s)    char *c, *a, *b;    // does sbrk() return the expected failure value? -  a = sbrk(TOOMUCH); -  if(a != (char*)0xffffffffffffffffL){ -    printf("%s: sbrk(<toomuch>) returned %p\n", a); +  pid = fork(); +  if(pid < 0){ +    printf("fork failed in sbrkbasic\n"); +    exit(1); +  } +  if(pid == 0){ +    a = sbrk(TOOMUCH); +    if(a == (char*)0xffffffffffffffffL){ +      // it's OK if this fails. +      exit(0); +    } +     +    for(b = a; b < a+TOOMUCH; b += 4096){ +      *b = 99; +    } +     +    // we should not get here! either sbrk(TOOMUCH) +    // should have failed, or (with lazy allocation) +    // a pagefault should have killed this process. +    exit(1); +  } + +  wait(&xstatus); +  if(xstatus == 1){ +    printf("%s: too much memory allocated!\n", s);      exit(1);    } @@ -2093,12 +2120,7 @@ sbrkfail(char *s)    for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){      if((pids[i] = fork()) == 0){        // allocate a lot of memory -      char *p0 = sbrk(BIG - (uint64)sbrk(0)); -      if((uint64)p0 != 0xffffffffffffffffLL){ -        char *p1 = sbrk(0); -        for(char *p2 = p0; p2 < p1; p2 += 4096) -          *p2 = 1; -      } +      sbrk(BIG - (uint64)sbrk(0));        write(fds[1], "x", 1);        // sit around until killed        for(;;) sleep(1000); @@ -2128,18 +2150,22 @@ sbrkfail(char *s)      exit(1);    }    if(pid == 0){ -    // allocate a lot of memory +    // allocate a lot of memory. +    // this should produce a page fault, +    // and thus not complete.      a = sbrk(0);      sbrk(10*BIG);      int n = 0;      for (i = 0; i < 10*BIG; i += PGSIZE) {        n += *(a+i);      } +    // print n so the compiler doesn't optimize away +    // the for loop.      printf("%s: allocate a lot of memory succeeded %d\n", n);      exit(1);    }    wait(&xstatus); -  if(xstatus != -1) +  if(xstatus != -1 && xstatus != 2)      exit(1);  } @@ -2502,23 +2528,67 @@ execout(char *s)  //  // use sbrk() to count how many free physical memory pages there are. +// touches the pages to force allocation. +// because out of memory with lazy allocation results in the process +// taking a fault and being killed, fork and report back.  //  int  countfree()  { -  uint64 sz0 = (uint64)sbrk(0); -  int n = 0; +  int fds[2]; + +  if(pipe(fds) < 0){ +    printf("pipe() failed in countfree()\n"); +    exit(1); +  } +   +  int pid = fork(); + +  if(pid < 0){ +    printf("fork failed in countfree()\n"); +    exit(1); +  } + +  if(pid == 0){ +    close(fds[0]); +     +    while(1){ +      uint64 a = (uint64) sbrk(4096); +      if(a == 0xffffffffffffffff){ +        break; +      } + +      // modify the memory to make sure it's really allocated. +      *(char *)(a + 4096 - 1) = 1; + +      // report back one more page. +      if(write(fds[1], "x", 1) != 1){ +        printf("write() failed in countfree()\n"); +        exit(1); +      } +    } + +    exit(0); +  } +  close(fds[1]); + +  int n = 0;    while(1){ -    uint64 a = (uint64) sbrk(4096); -    if(a == 0xffffffffffffffff){ -      break; +    char c; +    int cc = read(fds[0], &c, 1); +    if(cc < 0){ +      printf("read() failed in countfree()\n"); +      exit(1);      } -    // modify the memory to make sure it's really allocated. -    *(char *)(a + 4096 - 1) = 1; +    if(cc == 0) +      break;      n += 1;    } -  sbrk(-((uint64)sbrk(0) - sz0)); + +  close(fds[0]); +  wait((int*)0); +      return n;  } @@ -2645,7 +2715,7 @@ main(int argc, char *argv[])        }        int free1 = countfree();        if(free1 < free0){ -        printf("FAILED -- lost some free pages\n"); +        printf("FAILED -- lost %d free pages\n", free0 - free1);          if(continuous != 2)            exit(1);        } @@ -2653,7 +2723,12 @@ main(int argc, char *argv[])    }    printf("usertests starting\n"); +#ifdef SOL_LAZY1 +  int free0 = 32*1024*1024; +#else    int free0 = countfree(); +  int free1 = 0; +#endif    int fail = 0;    for (struct test *t = tests; t->s != 0; t++) {      if((justone == 0) || strcmp(t->s, justone) == 0) { @@ -2665,8 +2740,8 @@ main(int argc, char *argv[])    if(fail){      printf("SOME TESTS FAILED\n");      exit(1); -  } else if(countfree() < free0){ -    printf("FAILED -- lost some free pages\n"); +  } else if((free1 = countfree()) < free0){ +    printf("FAILED -- lost some free pages %d (out of %d)\n", free1, free0);      exit(1);    } else {      printf("ALL TESTS PASSED\n"); | 
