summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README4
-rw-r--r--usertests.c36
-rw-r--r--vm.c11
3 files changed, 46 insertions, 5 deletions
diff --git a/README b/README
index c46ec2a..3ea05a7 100644
--- a/README
+++ b/README
@@ -20,8 +20,8 @@ The following people made contributions:
Cliff Frey (MP)
Xiao Yu (MP)
-In addition, we are grateful for the patches submitted by Greg Price,
-Yandong Mao, and Hitoshi Mitake.
+In addition, we are grateful for the patches contributed by Greg
+Price, Yandong Mao, and Hitoshi Mitake.
The code in the files that constitute xv6 is
Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox.
diff --git a/usertests.c b/usertests.c
index 670a4a8..7ec03fc 100644
--- a/usertests.c
+++ b/usertests.c
@@ -324,6 +324,7 @@ mem(void)
void *m1, *m2;
int pid, ppid;
+ printf(1, "mem test\n");
ppid = getpid();
if((pid = fork()) == 0){
m1 = 0;
@@ -1332,6 +1333,41 @@ sbrktest(void)
wait();
}
+ // if we run the system out of memory, does it clean up the last
+ // failed allocation?
+ sbrk(-(sbrk(0) - oldbrk));
+ int pids[32];
+ int fds[2];
+ if(pipe(fds) != 0){
+ printf(1, "pipe() failed\n");
+ exit();
+ }
+ for (i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
+ if ((pids[i] = fork()) == 0) {
+ // allocate the full 640K
+ sbrk((640 * 1024) - (uint)sbrk(0));
+ write(fds[1], "x", 1);
+ // sit around until killed
+ while (1) sleep(1000);
+ }
+ char scratch;
+ if (pids[i] != -1)
+ read(fds[0], &scratch, 1);
+ }
+ // if those failed allocations freed up the pages they did allocate,
+ // we'll be able to allocate here
+ c = sbrk(4096);
+ for (i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
+ if (pids[i] == -1)
+ continue;
+ kill(pids[i]);
+ wait();
+ }
+ if (c == (char*)0xffffffff) {
+ printf(stdout, "failed sbrk leaked memory\n");
+ exit();
+ }
+
if(sbrk(0) > oldbrk)
sbrk(-(sbrk(0) - oldbrk));
diff --git a/vm.c b/vm.c
index 8a57ca9..a60c915 100644
--- a/vm.c
+++ b/vm.c
@@ -195,7 +195,8 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
if(pte == 0 || (*pte & PTE_P) == 0){
char *mem = kalloc();
if(mem == 0){
- // XXX clean up?
+ cprintf("allocuvm out of memory\n");
+ deallocuvm(pgdir, addr, sz);
return 0;
}
memset(mem, 0, PGSIZE);
@@ -312,13 +313,17 @@ copyuvm(pde_t *pgdir, uint sz)
if(*pte & PTE_P){
pa = PTE_ADDR(*pte);
if (!(mem = kalloc()))
- return 0;
+ goto bad;
memmove(mem, (char *)pa, PGSIZE);
if (!mappages(d, (void *)i, PGSIZE, PADDR(mem), PTE_W|PTE_U))
- return 0;
+ goto bad;
}
}
return d;
+
+bad:
+ freevm(d);
+ return 0;
}
// Allocate one page table for the machine for the kernel address