aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-04-05 00:02:15 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-04-05 00:02:15 +0000
commit9cc1bb97bc33ab91cd35486165ca1da51c7cdec3 (patch)
tree7e1cbd0df7cdc84ec806fd27d00a85113d7564c1 /libgo/runtime
parent06ec98415ab559f97fe90f661d91c4f9427db42b (diff)
downloadgcc-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.c23
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");