summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2011-02-09 14:38:33 -0500
committerRuss Cox <rsc@golang.org>2011-02-09 14:38:33 -0500
commita1bf66eea4f71166f1c1c87e9b493199529ebb94 (patch)
treef4bae47d57f185a688d65463bb11da33b2f5f4f1
parent0cfaca42e6426cb513168af967b5d9a2aee08ddf (diff)
downloadgo-a1bf66eea4f71166f1c1c87e9b493199529ebb94.tar.gz
runtime: new allocation strategy for amd64
Do not reserve virtual address space. Instead, assume it will be there when we need it, and crash loudly if that assumption is violated. Reserving the address space gets charged to ulimit -v, which exceeds commonly set limits. http://groups.google.com/group/golang-dev/msg/7c477af5f5a8dd2c R=r, niemeyer CC=golang-dev http://codereview.appspot.com/4148045
-rw-r--r--src/pkg/runtime/freebsd/mem.c17
-rw-r--r--src/pkg/runtime/linux/mem.c17
-rwxr-xr-xtest/run4
3 files changed, 35 insertions, 3 deletions
diff --git a/src/pkg/runtime/freebsd/mem.c b/src/pkg/runtime/freebsd/mem.c
index cbae18718..f5bbfa6fa 100644
--- a/src/pkg/runtime/freebsd/mem.c
+++ b/src/pkg/runtime/freebsd/mem.c
@@ -33,6 +33,12 @@ runtime·SysFree(void *v, uintptr n)
void*
runtime·SysReserve(void *v, uintptr n)
{
+ // On 64-bit, people with ulimit -v set complain if we reserve too
+ // much address space. Instead, assume that the reservation is okay
+ // and check the assumption in SysMap.
+ if(sizeof(void*) == 8)
+ return v;
+
return runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
}
@@ -42,6 +48,17 @@ runtime·SysMap(void *v, uintptr n)
void *p;
mstats.sys += n;
+
+ // On 64-bit, we don't actually have v reserved, so tread carefully.
+ if(sizeof(void*) == 8) {
+ p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
+ if(p != v) {
+ runtime·printf("runtime: address space conflict: map(%v) = %v\n", v, p);
+ runtime·throw("runtime: address space conflict");
+ }
+ return;
+ }
+
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
if(p != v)
runtime·throw("runtime: cannot map pages in arena address space");
diff --git a/src/pkg/runtime/linux/mem.c b/src/pkg/runtime/linux/mem.c
index 3a83e7394..633ad0c62 100644
--- a/src/pkg/runtime/linux/mem.c
+++ b/src/pkg/runtime/linux/mem.c
@@ -39,6 +39,12 @@ runtime·SysFree(void *v, uintptr n)
void*
runtime·SysReserve(void *v, uintptr n)
{
+ // On 64-bit, people with ulimit -v set complain if we reserve too
+ // much address space. Instead, assume that the reservation is okay
+ // and check the assumption in SysMap.
+ if(sizeof(void*) == 8)
+ return v;
+
return runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
}
@@ -48,6 +54,17 @@ runtime·SysMap(void *v, uintptr n)
void *p;
mstats.sys += n;
+
+ // On 64-bit, we don't actually have v reserved, so tread carefully.
+ if(sizeof(void*) == 8) {
+ p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
+ if(p != v) {
+ runtime·printf("runtime: address space conflict: map(%v) = %v\n", v, p);
+ runtime·throw("runtime: address space conflict");
+ }
+ return;
+ }
+
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
if(p != v)
runtime·throw("runtime: cannot map pages in arena address space");
diff --git a/test/run b/test/run
index ec0195253..28d0caa0f 100755
--- a/test/run
+++ b/test/run
@@ -42,9 +42,7 @@ TMP2FILE=/tmp/gotest2-$$-$USER
# don't run the machine out of memory: limit individual processes to 4GB.
# on thresher, 3GB suffices to run the tests; with 2GB, peano fails.
-# Linux charges reserved but not mapped addresses to ulimit -v
-# so we have to use ulimit -m.
-ulimit -m 4000000
+ulimit -v 4000000
# no core files please
ulimit -c 0