summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorPatrick Palka <patrick@parcs.ath.cx>2013-08-30 12:54:22 -0400
committerPatrick Palka <patrick@parcs.ath.cx>2013-08-30 12:54:22 -0400
commit26bf3dd478dce53eb50c2ce13821d61e416e3fe7 (patch)
tree7b025b1eca208e96cf5e1916dd12f0054fda79ea /rts
parent6d755c08ca125d991a95fbdc3ae1dc0608b722f1 (diff)
parent85c1715d086bf2d35bc05133398f462919f2aa7b (diff)
downloadhaskell-26bf3dd478dce53eb50c2ce13821d61e416e3fe7.tar.gz
Merge branch 'master' into ghc-parmake-gsoc
Conflicts: compiler/main/DynFlags.hs compiler/utils/FastString.lhs
Diffstat (limited to 'rts')
-rw-r--r--rts/posix/OSMem.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c
index 26aebc2b44..5486a15616 100644
--- a/rts/posix/OSMem.c
+++ b/rts/posix/OSMem.c
@@ -112,6 +112,27 @@ my_mmap (void *addr, W_ size)
} else {
vm_protect(mach_task_self(),(vm_address_t)ret,size,FALSE,VM_PROT_READ|VM_PROT_WRITE);
}
+#elif linux_HOST_OS
+ ret = mmap(addr, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (ret == (void *)-1 && errno == EPERM) {
+ // Linux may return EPERM if it tried to give us
+ // a chunk of address space below mmap_min_addr,
+ // See Trac #7500.
+ if (addr != 0) {
+ // Try again with no hint address.
+ // It's not clear that this can ever actually help,
+ // but since our alternative is to abort, we may as well try.
+ ret = mmap(0, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ }
+ if (ret == (void *)-1 && errno == EPERM) {
+ // Linux is not willing to give us any mapping,
+ // so treat this as an out-of-memory condition
+ // (really out of virtual address space).
+ errno = ENOMEM;
+ }
+ }
#else
ret = mmap(addr, size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);