aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/mem_linux.c
diff options
context:
space:
mode:
authorPaul Borman <borman@google.com>2012-02-08 14:39:16 -0500
committerRuss Cox <rsc@golang.org>2012-02-08 14:39:16 -0500
commitd37a8b73c504c232084666b292f20debb397bd27 (patch)
tree05044135254dcb16a8292b7b56b6194eb1ee7576 /src/pkg/runtime/mem_linux.c
parent1127b229763811c5e90d4d96b2c9f150e816df1d (diff)
downloadgo-d37a8b73c504c232084666b292f20debb397bd27.tar.xz
runtime: drop to 32 bit malloc if 64 bit will not work
On 64 bit UML it is not possible to reserve memory at 0xF8<<32. Detect when linux cannot use these high virtual memory addresses and drop back to the 32 bit memory allocator. R=rsc, cw CC=golang-dev https://golang.org/cl/5634050
Diffstat (limited to 'src/pkg/runtime/mem_linux.c')
-rw-r--r--src/pkg/runtime/mem_linux.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/pkg/runtime/mem_linux.c b/src/pkg/runtime/mem_linux.c
index fdf02c2cac..47287939ad 100644
--- a/src/pkg/runtime/mem_linux.c
+++ b/src/pkg/runtime/mem_linux.c
@@ -73,9 +73,18 @@ 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)
+ // if we can reserve at least 64K and check the assumption in SysMap.
+ // Only user-mode Linux (UML) rejects these requests.
+ if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) {
+ p = runtime·mmap(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+ if (p != v) {
+ return nil;
+ }
+ runtime·munmap(p, 64<<10);
+
+
return v;
+ }
p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
if((uintptr)p < 4096 || -(uintptr)p < 4096) {
@@ -92,7 +101,7 @@ runtime·SysMap(void *v, uintptr n)
mstats.sys += n;
// On 64-bit, we don't actually have v reserved, so tread carefully.
- if(sizeof(void*) == 8) {
+ if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) {
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
if(p != v && addrspace_free(v, n)) {
// On some systems, mmap ignores v without