AtomicUnorderedMapUtils.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #pragma once
  17. #include <atomic>
  18. #include <cassert>
  19. #include <cstdint>
  20. #include <system_error>
  21. #include <folly/portability/SysMman.h>
  22. #include <folly/portability/Unistd.h>
  23. namespace folly {
  24. namespace detail {
  25. class MMapAlloc {
  26. private:
  27. size_t computeSize(size_t size) {
  28. long pagesize = sysconf(_SC_PAGESIZE);
  29. size_t mmapLength = ((size - 1) & ~(pagesize - 1)) + pagesize;
  30. assert(size <= mmapLength && mmapLength < size + pagesize);
  31. assert((mmapLength % pagesize) == 0);
  32. return mmapLength;
  33. }
  34. public:
  35. void* allocate(size_t size) {
  36. auto len = computeSize(size);
  37. int extraflags = 0;
  38. #if defined(MAP_POPULATE)
  39. extraflags |= MAP_POPULATE;
  40. #endif
  41. // MAP_HUGETLB is a perf win, but requires cooperation from the
  42. // deployment environment (and a change to computeSize()).
  43. void* mem = static_cast<void*>(mmap(
  44. nullptr,
  45. len,
  46. PROT_READ | PROT_WRITE,
  47. MAP_PRIVATE | MAP_ANONYMOUS | extraflags,
  48. -1,
  49. 0));
  50. if (mem == reinterpret_cast<void*>(-1)) {
  51. throw std::system_error(errno, std::system_category());
  52. }
  53. #if !defined(MAP_POPULATE) && defined(MADV_WILLNEED)
  54. madvise(mem, size, MADV_WILLNEED);
  55. #endif
  56. return mem;
  57. }
  58. void deallocate(void* p, size_t size) {
  59. auto len = computeSize(size);
  60. munmap(p, len);
  61. }
  62. };
  63. template <typename Allocator>
  64. struct GivesZeroFilledMemory : public std::false_type {};
  65. template <>
  66. struct GivesZeroFilledMemory<MMapAlloc> : public std::true_type {};
  67. } // namespace detail
  68. } // namespace folly