diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-04-05 00:02:15 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-04-05 00:02:15 +0000 |
commit | 9cc1bb97bc33ab91cd35486165ca1da51c7cdec3 (patch) | |
tree | 7e1cbd0df7cdc84ec806fd27d00a85113d7564c1 /libgo/runtime | |
parent | 06ec98415ab559f97fe90f661d91c4f9427db42b (diff) | |
download | gcc-9cc1bb97bc33ab91cd35486165ca1da51c7cdec3.zip gcc-9cc1bb97bc33ab91cd35486165ca1da51c7cdec3.tar.gz gcc-9cc1bb97bc33ab91cd35486165ca1da51c7cdec3.tar.bz2 |
libgo: Use MAP_FIXED if necessary to grab arena.
From Rainer Orth.
PR go/48240
* configure.ac: Check for mincore.
* configure: Regenerate.
* config.h.in: Regenerate.
* runtime/mem.c: Include unistd.h.
(addrspace_free): New function.
(runtime_SysMap): Retry 64-bit runtime_mmap with MAP_FIXED.
From-SVN: r171961
Diffstat (limited to 'libgo/runtime')
-rw-r--r-- | libgo/runtime/mem.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/libgo/runtime/mem.c b/libgo/runtime/mem.c index f62a4d3..90c2c61 100644 --- a/libgo/runtime/mem.c +++ b/libgo/runtime/mem.c @@ -1,4 +1,5 @@ #include <errno.h> +#include <unistd.h> #include "runtime.h" #include "malloc.h" @@ -16,6 +17,23 @@ static int dev_zero = -1; #endif +static _Bool +addrspace_free(void *v __attribute__ ((unused)), uintptr n __attribute__ ((unused))) +{ +#ifdef HAVE_MINCORE + size_t page_size = getpagesize(); + size_t off; + char one_byte; + + errno = 0; + for(off = 0; off < n; off += page_size) + if(mincore((char *)v + off, page_size, (void *)&one_byte) != -1 + || errno != ENOMEM) + return 0; +#endif + return 1; +} + void* runtime_SysAlloc(uintptr n) { @@ -109,6 +127,11 @@ runtime_SysMap(void *v, uintptr 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, fd, 0); + if(p != v && addrspace_free(v, n)) { + // On some systems, mmap ignores v without + // MAP_FIXED, so retry if the address space is free. + p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, fd, 0); + } if(p != v) { runtime_printf("runtime: address space conflict: map(%p) = %p\n", v, p); runtime_throw("runtime: address space conflict"); |