mmap.cc 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright (c) Meta Platforms, Inc. and affiliates.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #include "port/mmap.h"
  6. #include <cassert>
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <new>
  10. #include <utility>
  11. #include "util/hash.h"
  12. namespace ROCKSDB_NAMESPACE {
  13. MemMapping::~MemMapping() {
  14. #ifdef OS_WIN
  15. if (addr_ != nullptr) {
  16. (void)::UnmapViewOfFile(addr_);
  17. }
  18. if (page_file_handle_ != NULL) {
  19. (void)::CloseHandle(page_file_handle_);
  20. }
  21. #else // OS_WIN -> !OS_WIN
  22. if (addr_ != nullptr) {
  23. auto status = munmap(addr_, length_);
  24. assert(status == 0);
  25. if (status != 0) {
  26. // TODO: handle error?
  27. }
  28. }
  29. #endif // OS_WIN
  30. }
  31. MemMapping::MemMapping(MemMapping&& other) noexcept {
  32. *this = std::move(other);
  33. }
  34. MemMapping& MemMapping::operator=(MemMapping&& other) noexcept {
  35. if (&other == this) {
  36. return *this;
  37. }
  38. this->~MemMapping();
  39. std::memcpy(static_cast<void*>(this), &other, sizeof(*this));
  40. new (&other) MemMapping();
  41. return *this;
  42. }
  43. MemMapping MemMapping::AllocateAnonymous(size_t length, bool huge) {
  44. MemMapping mm;
  45. mm.length_ = length;
  46. assert(mm.addr_ == nullptr);
  47. if (length == 0) {
  48. // OK to leave addr as nullptr
  49. return mm;
  50. }
  51. int huge_flag = 0;
  52. #ifdef OS_WIN
  53. if (huge) {
  54. #ifdef FILE_MAP_LARGE_PAGES
  55. huge_flag = FILE_MAP_LARGE_PAGES;
  56. #endif // FILE_MAP_LARGE_PAGES
  57. }
  58. mm.page_file_handle_ = ::CreateFileMapping(
  59. INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE | SEC_COMMIT,
  60. Upper32of64(length), Lower32of64(length), nullptr);
  61. if (mm.page_file_handle_ == NULL) {
  62. // Failure
  63. return mm;
  64. }
  65. mm.addr_ = ::MapViewOfFile(mm.page_file_handle_, FILE_MAP_WRITE | huge_flag,
  66. 0, 0, length);
  67. #else // OS_WIN -> !OS_WIN
  68. if (huge) {
  69. #ifdef MAP_HUGETLB
  70. huge_flag = MAP_HUGETLB;
  71. #endif // MAP_HUGE_TLB
  72. }
  73. mm.addr_ = mmap(nullptr, length, PROT_READ | PROT_WRITE,
  74. MAP_PRIVATE | MAP_ANONYMOUS | huge_flag, -1, 0);
  75. if (mm.addr_ == MAP_FAILED) {
  76. mm.addr_ = nullptr;
  77. }
  78. #endif // OS_WIN
  79. return mm;
  80. }
  81. MemMapping MemMapping::AllocateHuge(size_t length) {
  82. return AllocateAnonymous(length, /*huge*/ true);
  83. }
  84. MemMapping MemMapping::AllocateLazyZeroed(size_t length) {
  85. return AllocateAnonymous(length, /*huge*/ false);
  86. }
  87. } // namespace ROCKSDB_NAMESPACE