Apache Arrow (C++)
A columnar in-memory analytics layer designed to accelerate big data.
mman.h
Go to the documentation of this file.
1 // Copyright https://code.google.com/p/mman-win32/
2 //
3 // Licensed under the MIT License;
4 // You may obtain a copy of the License at
5 //
6 // https://opensource.org/licenses/MIT
7 
8 #ifndef _MMAN_WIN32_H
9 #define _MMAN_WIN32_H
10 
11 // Allow use of features specific to Windows XP or later.
12 #ifndef _WIN32_WINNT
13 // Change this to the appropriate value to target other versions of Windows.
14 #define _WIN32_WINNT 0x0501
15 
16 #endif
17 
18 #include <errno.h>
19 #include <io.h>
20 #include <sys/types.h>
21 #include <windows.h>
22 
23 #define PROT_NONE 0
24 #define PROT_READ 1
25 #define PROT_WRITE 2
26 #define PROT_EXEC 4
27 
28 #define MAP_FILE 0
29 #define MAP_SHARED 1
30 #define MAP_PRIVATE 2
31 #define MAP_TYPE 0xf
32 #define MAP_FIXED 0x10
33 #define MAP_ANONYMOUS 0x20
34 #define MAP_ANON MAP_ANONYMOUS
35 
36 #define MAP_FAILED ((void*)-1)
37 
38 /* Flags for msync. */
39 #define MS_ASYNC 1
40 #define MS_SYNC 2
41 #define MS_INVALIDATE 4
42 
43 #ifndef FILE_MAP_EXECUTE
44 #define FILE_MAP_EXECUTE 0x0020
45 #endif
46 
47 static int __map_mman_error(const DWORD err, const int deferr) {
48  if (err == 0) return 0;
49  // TODO: implement
50  return err;
51 }
52 
53 static DWORD __map_mmap_prot_page(const int prot) {
54  DWORD protect = 0;
55 
56  if (prot == PROT_NONE) return protect;
57 
58  if ((prot & PROT_EXEC) != 0) {
59  protect = ((prot & PROT_WRITE) != 0) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
60  } else {
61  protect = ((prot & PROT_WRITE) != 0) ? PAGE_READWRITE : PAGE_READONLY;
62  }
63 
64  return protect;
65 }
66 
67 static DWORD __map_mmap_prot_file(const int prot) {
68  DWORD desiredAccess = 0;
69 
70  if (prot == PROT_NONE) return desiredAccess;
71 
72  if ((prot & PROT_READ) != 0) desiredAccess |= FILE_MAP_READ;
73  if ((prot & PROT_WRITE) != 0) desiredAccess |= FILE_MAP_WRITE;
74  if ((prot & PROT_EXEC) != 0) desiredAccess |= FILE_MAP_EXECUTE;
75 
76  return desiredAccess;
77 }
78 
79 static void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off) {
80  HANDLE fm, h;
81 
82  void* map = MAP_FAILED;
83 
84 #ifdef _MSC_VER
85 #pragma warning(push)
86 #pragma warning(disable : 4293)
87 #endif
88 
89  const DWORD dwFileOffsetLow =
90  (sizeof(off_t) <= sizeof(DWORD)) ? (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
91  const DWORD dwFileOffsetHigh =
92  (sizeof(off_t) <= sizeof(DWORD)) ? (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
93  const DWORD protect = __map_mmap_prot_page(prot);
94  const DWORD desiredAccess = __map_mmap_prot_file(prot);
95 
96  const size_t maxSize = off + len;
97 
98  const DWORD dwMaxSizeLow = static_cast<DWORD>(maxSize & 0xFFFFFFFFL);
99  const DWORD dwMaxSizeHigh = static_cast<DWORD>((maxSize >> 32) & 0xFFFFFFFFL);
100 
101 #ifdef _MSC_VER
102 #pragma warning(pop)
103 #endif
104 
105  errno = 0;
106 
107  if (len == 0
108  /* Unsupported flag combinations */
109  || (flags & MAP_FIXED) != 0
110  /* Usupported protection combinations */
111  || prot == PROT_EXEC) {
112  errno = EINVAL;
113  return MAP_FAILED;
114  }
115 
116  h = ((flags & MAP_ANONYMOUS) == 0) ? (HANDLE)_get_osfhandle(fildes)
117  : INVALID_HANDLE_VALUE;
118 
119  if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) {
120  errno = EBADF;
121  return MAP_FAILED;
122  }
123 
124  fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
125 
126  if (fm == NULL) {
127  errno = __map_mman_error(GetLastError(), EPERM);
128  return MAP_FAILED;
129  }
130 
131  map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
132 
133  CloseHandle(fm);
134 
135  if (map == NULL) {
136  errno = __map_mman_error(GetLastError(), EPERM);
137  return MAP_FAILED;
138  }
139 
140  return map;
141 }
142 
143 static int munmap(void* addr, size_t len) {
144  if (UnmapViewOfFile(addr)) return 0;
145 
146  errno = __map_mman_error(GetLastError(), EPERM);
147 
148  return -1;
149 }
150 
151 static int mprotect(void* addr, size_t len, int prot) {
152  DWORD newProtect = __map_mmap_prot_page(prot);
153  DWORD oldProtect = 0;
154 
155  if (VirtualProtect(addr, len, newProtect, &oldProtect)) return 0;
156 
157  errno = __map_mman_error(GetLastError(), EPERM);
158 
159  return -1;
160 }
161 
162 static int msync(void* addr, size_t len, int flags) {
163  if (FlushViewOfFile(addr, len)) return 0;
164 
165  errno = __map_mman_error(GetLastError(), EPERM);
166 
167  return -1;
168 }
169 
170 static int mlock(const void* addr, size_t len) {
171  if (VirtualLock((LPVOID)addr, len)) return 0;
172 
173  errno = __map_mman_error(GetLastError(), EPERM);
174 
175  return -1;
176 }
177 
178 static int munlock(const void* addr, size_t len) {
179  if (VirtualUnlock((LPVOID)addr, len)) return 0;
180 
181  errno = __map_mman_error(GetLastError(), EPERM);
182 
183  return -1;
184 }
185 
186 #endif
#define FILE_MAP_EXECUTE
Definition: mman.h:44
#define MAP_FAILED
Definition: mman.h:36
#define PROT_WRITE
Definition: mman.h:25
#define PROT_READ
Definition: mman.h:24
#define MAP_FIXED
Definition: mman.h:32
#define PROT_NONE
Definition: mman.h:23
#define MAP_ANONYMOUS
Definition: mman.h:33
#define PROT_EXEC
Definition: mman.h:26