1 /* 2 * Copyright 2015-present Facebook, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <atomic> 20 #include <cassert> 21 #include <cstdint> 22 #include <system_error> 23 24 #include <folly/portability/SysMman.h> 25 #include <folly/portability/Unistd.h> 26 27 namespace folly { 28 namespace detail { 29 30 class MMapAlloc { 31 private: computeSize(size_t size)32 size_t computeSize(size_t size) { 33 long pagesize = sysconf(_SC_PAGESIZE); 34 size_t mmapLength = ((size - 1) & ~(pagesize - 1)) + pagesize; 35 assert(size <= mmapLength && mmapLength < size + pagesize); 36 assert((mmapLength % pagesize) == 0); 37 return mmapLength; 38 } 39 40 public: allocate(size_t size)41 void* allocate(size_t size) { 42 auto len = computeSize(size); 43 44 int extraflags = 0; 45 #if defined(MAP_POPULATE) 46 extraflags |= MAP_POPULATE; 47 #endif 48 // MAP_HUGETLB is a perf win, but requires cooperation from the 49 // deployment environment (and a change to computeSize()). 50 void* mem = static_cast<void*>(mmap( 51 nullptr, 52 len, 53 PROT_READ | PROT_WRITE, 54 MAP_PRIVATE | MAP_ANONYMOUS | extraflags, 55 -1, 56 0)); 57 if (mem == reinterpret_cast<void*>(-1)) { 58 throw std::system_error(errno, std::system_category()); 59 } 60 #if !defined(MAP_POPULATE) && defined(MADV_WILLNEED) 61 madvise(mem, size, MADV_WILLNEED); 62 #endif 63 64 return mem; 65 } 66 deallocate(void * p,size_t size)67 void deallocate(void* p, size_t size) { 68 auto len = computeSize(size); 69 munmap(p, len); 70 } 71 }; 72 73 template <typename Allocator> 74 struct GivesZeroFilledMemory : public std::false_type {}; 75 76 template <> 77 struct GivesZeroFilledMemory<MMapAlloc> : public std::true_type {}; 78 79 } // namespace detail 80 } // namespace folly 81