diff options
author | Patrick Palka <patrick@parcs.ath.cx> | 2013-08-30 12:54:22 -0400 |
---|---|---|
committer | Patrick Palka <patrick@parcs.ath.cx> | 2013-08-30 12:54:22 -0400 |
commit | 26bf3dd478dce53eb50c2ce13821d61e416e3fe7 (patch) | |
tree | 7b025b1eca208e96cf5e1916dd12f0054fda79ea /rts | |
parent | 6d755c08ca125d991a95fbdc3ae1dc0608b722f1 (diff) | |
parent | 85c1715d086bf2d35bc05133398f462919f2aa7b (diff) | |
download | haskell-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.c | 21 |
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); |