diff options
| author | Paul Borman <borman@google.com> | 2012-02-08 14:39:16 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2012-02-08 14:39:16 -0500 |
| commit | d37a8b73c504c232084666b292f20debb397bd27 (patch) | |
| tree | 05044135254dcb16a8292b7b56b6194eb1ee7576 /src/pkg/runtime/mem_linux.c | |
| parent | 1127b229763811c5e90d4d96b2c9f150e816df1d (diff) | |
| download | go-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.c | 15 |
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 |
