diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-05 00:02:15 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-05 00:02:15 +0000 |
commit | 00149290a194fe51f26d37ac5a37c536ddaa7b44 (patch) | |
tree | 7e1cbd0df7cdc84ec806fd27d00a85113d7564c1 | |
parent | b8439d263974fb29dc3ff2ed7bf1f127b391bf42 (diff) | |
download | gcc-00149290a194fe51f26d37ac5a37c536ddaa7b44.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171961 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libgo/config.h.in | 12 | ||||
-rwxr-xr-x | libgo/configure | 2 | ||||
-rw-r--r-- | libgo/configure.ac | 2 | ||||
-rw-r--r-- | libgo/runtime/mem.c | 23 |
4 files changed, 37 insertions, 2 deletions
diff --git a/libgo/config.h.in b/libgo/config.h.in index d6f6ac1aec4..2976e979a36 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -15,6 +15,9 @@ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `mincore' function. */ +#undef HAVE_MINCORE + /* Define to 1 if the system has the type `off64_t'. */ #undef HAVE_OFF64_T @@ -30,6 +33,9 @@ /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H +/* Define to 1 if you have the `strerror_r' function. */ +#undef HAVE_STRERROR_R + /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H @@ -59,6 +65,9 @@ /* Define to 1 if you have the <sys/ptrace.h> header file. */ #undef HAVE_SYS_PTRACE_H +/* Define to 1 if you have the <sys/select.h> header file. */ +#undef HAVE_SYS_SELECT_H + /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H @@ -77,6 +86,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `wait4' function. */ +#undef HAVE_WAIT4 + /* Define if the C++ compiler is configured for setjmp/longjmp exceptions. */ #undef LIBGO_SJLJ_EXCEPTIONS diff --git a/libgo/configure b/libgo/configure index 2821967d49a..611103fc4b5 100755 --- a/libgo/configure +++ b/libgo/configure @@ -14266,7 +14266,7 @@ else fi -for ac_func in srandom random strerror_r strsignal wait4 +for ac_func in srandom random strerror_r strsignal wait4 mincore do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/libgo/configure.ac b/libgo/configure.ac index 77b9f94aba0..e772c2a12de 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -426,7 +426,7 @@ esac AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h) AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes) -AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4) +AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore) AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes) AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes) diff --git a/libgo/runtime/mem.c b/libgo/runtime/mem.c index f62a4d37ee7..90c2c61aff9 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"); |