mmap_wrapper.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "include/mmap_wrapper.hxx"
  2. #define DEBUG
  3. // WIN32 =============================================================================================
  4. #ifdef _WIN32
  5. // UNIX =============================================================================================
  6. #else
  7. #include <unistd.h>
  8. #include <sys/mman.h>
  9. #endif
  10. using namespace pmmf;
  11. extern void* pmmf::mmap(void* start, size_t length, ProtectionMode prot, MapFlag flags, FileDescriptor fd, off_t offset) {
  12. #ifndef _WIN32
  13. int __prot = ( ( (int)0x00 )
  14. | ( ( (int)prot & (int)ProtectionMode::read ) ? PROT_READ : 0x00 )
  15. | ( ( (int)prot & (int)ProtectionMode::write ) ? PROT_WRITE : 0x00 )
  16. | ( ( (int)prot & (int)ProtectionMode::exec ) ? PROT_EXEC : 0x00 ) );
  17. int __flags = ( ( (int)0x00 )
  18. | ( ( (int)flags & (int)MapFlag::anonymous ) ? MAP_ANONYMOUS : 0x00 )
  19. | ( ( (int)flags & (int)MapFlag::priv ) ? MAP_PRIVATE : 0x00 )
  20. | ( ( (int)flags & (int)MapFlag::shared ) ? MAP_SHARED : 0x00 )
  21. | ( ( (int)flags & (int)MapFlag::denywrite ) ? MAP_DENYWRITE : 0x00 )
  22. | ( ( (int)flags & (int)MapFlag::executable ) ? MAP_EXECUTABLE : 0x00 )
  23. | ( ( (int)flags & (int)MapFlag::noreserve ) ? MAP_NORESERVE : 0x00 )
  24. | ( ( (int)flags & (int)MapFlag::locked ) ? MAP_LOCKED : 0x00 )
  25. | ( ( (int)flags & (int)MapFlag::growsdown ) ? MAP_GROWSDOWN : 0x00 )
  26. | ( ( (int)flags & (int)MapFlag::file ) ? MAP_FILE : 0x00 ) );
  27. return ::mmap(start, length, __prot, __flags, fd, static_cast<off_t>(offset));
  28. #else
  29. if(fd == INVALID_FILE_DESCRIPTOR && (!((int)flags & (int)MapFlag::anon) || offset))
  30. return MAP_FAILED;
  31. DWORD protect =
  32. ((int)prot & (int)ProtectionMode::write)
  33. ? ((int)prot & (int)ProtectionMode::exec)
  34. ? PAGE_EXECUTE_READWRITE
  35. : PAGE_READWRITE
  36. : ((int)prot & (int)ProtectionMode::exec)
  37. ? ((int)prot & (int)ProtectionMode::read)
  38. ? PAGE_EXECUTE_READ
  39. : PAGE_EXECUTE
  40. : ((int)prot & (int)ProtectionMode::read)
  41. ? PAGE_READONLY
  42. : PAGE_NOACCESS;
  43. HANDLE map_handle;
  44. if constexpr (sizeof(off_t) <= sizeof(DWORD)) {
  45. map_handle = CreateFileMapping(fd, nullptr, protect, 0, static_cast<DWORD>(offset + static_cast<off_t>(length)), nullptr);
  46. } else {
  47. const off_t max_size = offset + static_cast<off_t>(length);
  48. map_handle = CreateFileMapping(fd, nullptr, protect, static_cast<DWORD>((max_size >> 32) & 0xFFFFFFFFL), static_cast<DWORD>(max_size & 0xFFFFFFFFL), nullptr);
  49. }
  50. if(map_handle == nullptr)
  51. return MAP_FAILED;
  52. DWORD dwDesiredAccess = 0
  53. | (((int)prot & (int)ProtectionMode::write) ? FILE_MAP_WRITE : 0)
  54. | (((int)prot & (int)ProtectionMode::read) ? FILE_MAP_READ : 0)
  55. | (((int)prot & (int)ProtectionMode::exec) ? FILE_MAP_EXECUTE : 0)
  56. | (((int)flags & (int)MapFlag::priv) ? FILE_MAP_COPY : 0);
  57. void* start_page_pointer;
  58. if((int)flags & (int)MapFlag::fixed) {
  59. if constexpr (sizeof(off_t) <= sizeof(DWORD)) {
  60. start_page_pointer = MapViewOfFileEx(map_handle, dwDesiredAccess, 0, static_cast<DWORD>(offset), length, start);
  61. } else {
  62. start_page_pointer = MapViewOfFileEx(map_handle, dwDesiredAccess, static_cast<DWORD>((offset >> 32) & 0xFFFFFFFFL), static_cast<DWORD>(offset & 0xFFFFFFFFL), length, start);
  63. }
  64. } else {
  65. if constexpr (sizeof(off_t) <= sizeof(DWORD)) {
  66. start_page_pointer = MapViewOfFile(map_handle, dwDesiredAccess, 0, static_cast<DWORD>(offset), length);
  67. } else {
  68. start_page_pointer = MapViewOfFile(map_handle, dwDesiredAccess, static_cast<DWORD>((offset >> 32) & 0xFFFFFFFFL), static_cast<DWORD>(offset & 0xFFFFFFFFL), length);
  69. }
  70. }
  71. if(start_page_pointer == nullptr) {
  72. CloseHandle(map_handle);
  73. return MAP_FAILED;
  74. }
  75. CloseHandle(map_handle);
  76. return start_page_pointer;
  77. #endif
  78. }
  79. extern void pmmf::munmap(void *addr, std::size_t length) {
  80. #ifndef _WIN32
  81. ::munmap(addr, length);
  82. #else
  83. UnmapViewOfFile(addr);
  84. #endif
  85. }
  86. extern int pmmf::msync(FileDescriptor file_descriptor, void* start, size_t length, int flags) {
  87. #ifdef _WIN32
  88. return (::FlushViewOfFile(start, 0))
  89. ? (::FlushFileBuffers(file_descriptor))
  90. ? 0
  91. : -1
  92. : -1;
  93. #else
  94. return ::msync(start, length, MS_SYNC);
  95. #endif
  96. }