fix usertests to pass all the riscv-sol-fall20 solutions.

This commit is contained in:
Robert Morris 2020-08-27 06:21:10 -04:00
parent efaa7b8e2a
commit d7e5f26910

View file

@ -997,6 +997,11 @@ mem(char *s)
} else { } else {
int xstatus; int xstatus;
wait(&xstatus); wait(&xstatus);
if(xstatus == -1){
// probably page fault, so might be lazy lab,
// so OK.
exit(0);
}
exit(xstatus); exit(xstatus);
} }
} }
@ -1955,9 +1960,31 @@ sbrkbasic(char *s)
char *c, *a, *b; char *c, *a, *b;
// does sbrk() return the expected failure value? // does sbrk() return the expected failure value?
a = sbrk(TOOMUCH); pid = fork();
if(a != (char*)0xffffffffffffffffL){ if(pid < 0){
printf("%s: sbrk(<toomuch>) returned %p\n", a); 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); exit(1);
} }
@ -2093,12 +2120,7 @@ sbrkfail(char *s)
for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
if((pids[i] = fork()) == 0){ if((pids[i] = fork()) == 0){
// allocate a lot of memory // allocate a lot of memory
char *p0 = sbrk(BIG - (uint64)sbrk(0)); sbrk(BIG - (uint64)sbrk(0));
if((uint64)p0 != 0xffffffffffffffffLL){
char *p1 = sbrk(0);
for(char *p2 = p0; p2 < p1; p2 += 4096)
*p2 = 1;
}
write(fds[1], "x", 1); write(fds[1], "x", 1);
// sit around until killed // sit around until killed
for(;;) sleep(1000); for(;;) sleep(1000);
@ -2128,18 +2150,22 @@ sbrkfail(char *s)
exit(1); exit(1);
} }
if(pid == 0){ 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); a = sbrk(0);
sbrk(10*BIG); sbrk(10*BIG);
int n = 0; int n = 0;
for (i = 0; i < 10*BIG; i += PGSIZE) { for (i = 0; i < 10*BIG; i += PGSIZE) {
n += *(a+i); 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); printf("%s: allocate a lot of memory succeeded %d\n", n);
exit(1); exit(1);
} }
wait(&xstatus); wait(&xstatus);
if(xstatus != -1) if(xstatus != -1 && xstatus != 2)
exit(1); exit(1);
} }
@ -2502,23 +2528,67 @@ execout(char *s)
// //
// use sbrk() to count how many free physical memory pages there are. // 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 int
countfree() countfree()
{ {
uint64 sz0 = (uint64)sbrk(0); int fds[2];
int n = 0;
while(1){ if(pipe(fds) < 0){
uint64 a = (uint64) sbrk(4096); printf("pipe() failed in countfree()\n");
if(a == 0xffffffffffffffff){ exit(1);
break; }
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);
}
} }
// modify the memory to make sure it's really allocated.
*(char *)(a + 4096 - 1) = 1; exit(0);
}
close(fds[1]);
int n = 0;
while(1){
char c;
int cc = read(fds[0], &c, 1);
if(cc < 0){
printf("read() failed in countfree()\n");
exit(1);
}
if(cc == 0)
break;
n += 1; n += 1;
} }
sbrk(-((uint64)sbrk(0) - sz0));
close(fds[0]);
wait((int*)0);
return n; return n;
} }
@ -2645,7 +2715,7 @@ main(int argc, char *argv[])
} }
int free1 = countfree(); int free1 = countfree();
if(free1 < free0){ if(free1 < free0){
printf("FAILED -- lost some free pages\n"); printf("FAILED -- lost %d free pages\n", free0 - free1);
if(continuous != 2) if(continuous != 2)
exit(1); exit(1);
} }
@ -2653,7 +2723,12 @@ main(int argc, char *argv[])
} }
printf("usertests starting\n"); printf("usertests starting\n");
#ifdef SOL_LAZY1
int free0 = 32*1024*1024;
#else
int free0 = countfree(); int free0 = countfree();
int free1 = 0;
#endif
int fail = 0; int fail = 0;
for (struct test *t = tests; t->s != 0; t++) { for (struct test *t = tests; t->s != 0; t++) {
if((justone == 0) || strcmp(t->s, justone) == 0) { if((justone == 0) || strcmp(t->s, justone) == 0) {
@ -2665,8 +2740,8 @@ main(int argc, char *argv[])
if(fail){ if(fail){
printf("SOME TESTS FAILED\n"); printf("SOME TESTS FAILED\n");
exit(1); exit(1);
} else if(countfree() < free0){ } else if((free1 = countfree()) < free0){
printf("FAILED -- lost some free pages\n"); printf("FAILED -- lost some free pages %d (out of %d)\n", free1, free0);
exit(1); exit(1);
} else { } else {
printf("ALL TESTS PASSED\n"); printf("ALL TESTS PASSED\n");