X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fportability%2FSysMman.cpp;h=af76d8bb25398e898bc1578c0d0c0bb5100a5f24;hb=70230b7a106820807c8d74fcf3d21ebab3442fbb;hp=9827f045dd6731d8999d87937880bce1e18678ad;hpb=59bcc4529e8d3490612ce6f41e6ba36226dcb93b;p=folly.git diff --git a/folly/portability/SysMman.cpp b/folly/portability/SysMman.cpp old mode 100755 new mode 100644 index 9827f045..af76d8bb --- a/folly/portability/SysMman.cpp +++ b/folly/portability/SysMman.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ #include #ifdef _WIN32 + #include + #include #include @@ -56,7 +58,7 @@ static size_t alignToAllocationGranularity(size_t s) { } extern "C" { -int madvise(const void* addr, size_t len, int advise) { +int madvise(const void* /* addr */, size_t /* len */, int /* advise */) { // We do nothing at all. // Could probably implement dontneed via VirtualAlloc // with the MEM_RESET and MEM_RESET_UNDO flags. @@ -64,12 +66,27 @@ int madvise(const void* addr, size_t len, int advise) { } int mlock(const void* addr, size_t len) { + // For some strange reason, it's allowed to + // lock a nullptr as long as length is zero. + // VirtualLock doesn't allow it, so handle + // it specially. + if (addr == nullptr && len == 0) { + return 0; + } if (!VirtualLock((void*)addr, len)) { return -1; } return 0; } +namespace { +constexpr uint32_t kMMapLengthMagic = 0xFACEB00C; +struct MemMapDebugTrailer { + size_t length; + uint32_t magic; +}; +} + void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) { // Make sure it's something we support first. @@ -106,10 +123,13 @@ void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) { (DWORD)((length >> 32) & 0xFFFFFFFF), (DWORD)(length & 0xFFFFFFFF), nullptr); + if (fmh == nullptr) { + return MAP_FAILED; + } ret = MapViewOfFileEx( fmh, accessFlags, - (DWORD)((off >> 32) & 0xFFFFFFFF), + (DWORD)(0), // off_t is only 32-bit :( (DWORD)(off & 0xFFFFFFFF), 0, addr); @@ -118,6 +138,14 @@ void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) { } CloseHandle(fmh); } else { + auto baseLength = length; + if (folly::kIsDebug) { + // In debug mode we keep track of the length to make + // sure you're only munmapping the entire thing if + // we're using VirtualAlloc. + length += sizeof(MemMapDebugTrailer); + } + // VirtualAlloc rounds size down to a multiple // of the system allocation granularity :( length = alignToAllocationGranularity(length); @@ -125,6 +153,12 @@ void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) { if (ret == nullptr) { return MAP_FAILED; } + + if (folly::kIsDebug) { + auto deb = (MemMapDebugTrailer*)((char*)ret + baseLength); + deb->length = baseLength; + deb->magic = kMMapLengthMagic; + } } // TODO: Could technically implement MAP_POPULATE via PrefetchVirtualMemory @@ -148,6 +182,10 @@ int mprotect(void* addr, size_t size, int prot) { } int munlock(const void* addr, size_t length) { + // See comment in mlock + if (addr == nullptr && length == 0) { + return 0; + } if (!VirtualUnlock((void*)addr, length)) { return -1; } @@ -163,8 +201,11 @@ int munmap(void* addr, size_t length) { // in debug mode. MEMORY_BASIC_INFORMATION inf; VirtualQuery(addr, &inf, sizeof(inf)); - assert(inf.BaseAddress == addr); - assert(inf.RegionSize == alignToAllocationGranularity(length)); + assert(inf.AllocationBase == addr); + + auto deb = (MemMapDebugTrailer*)((char*)addr + length); + assert(deb->length == length); + assert(deb->magic == kMMapLengthMagic); } if (!VirtualFree(addr, 0, MEM_RELEASE)) { return -1; @@ -174,4 +215,5 @@ int munmap(void* addr, size_t length) { return 0; } } + #endif