2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * The Original Code is Copyright (C) 2008 Blender Foundation.
17 * All rights reserved.
29 # include <sys/types.h>
32 # include "mmap_win.h"
34 # ifndef FILE_MAP_EXECUTE
35 // not defined in earlier versions of the Platform SDK (before February 2003)
36 # define FILE_MAP_EXECUTE 0x0020
39 /* copied from BLI_utildefines.h, ugh */
41 # define UNUSED(x) UNUSED_##x __attribute__((__unused__))
46 /* --------------------------------------------------------------------- */
47 /* local storage definitions */
48 /* --------------------------------------------------------------------- */
49 /* all memory mapped chunks are put in linked lists */
50 typedef struct mmapLink {
51 struct mmapLink *next, *prev;
54 typedef struct mmapListBase {
58 typedef struct MemMap {
59 struct MemMap *next, *prev;
65 /* --------------------------------------------------------------------- */
67 /* --------------------------------------------------------------------- */
69 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink);
70 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink);
71 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr);
73 static int mmap_get_prot_flags(int flags);
74 static int mmap_get_access_flags(int flags);
76 /* --------------------------------------------------------------------- */
78 /* --------------------------------------------------------------------- */
79 volatile static struct mmapListBase _mmapbase;
80 volatile static struct mmapListBase *mmapbase = &_mmapbase;
82 /* --------------------------------------------------------------------- */
84 /* --------------------------------------------------------------------- */
86 /* mmap for windows */
87 void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t offset)
89 HANDLE fhandle = INVALID_HANDLE_VALUE;
91 int prot_flags = mmap_get_prot_flags(prot);
92 int access_flags = mmap_get_access_flags(prot);
96 if (flags & MAP_FIXED) {
108 fhandle = (HANDLE)_get_osfhandle(fd);
110 if (fhandle == INVALID_HANDLE_VALUE) {
111 if (!(flags & MAP_ANONYMOUS)) {
117 if (!DuplicateHandle(GetCurrentProcess(),
123 DUPLICATE_SAME_ACCESS)) {
128 /* Split 64 bit size into low and high bits. */
129 DWORD len_bits_high = len >> 32;
130 DWORD len_bits_low = len & 0xFFFFFFFF;
132 maphandle = CreateFileMapping(fhandle, NULL, prot_flags, len_bits_high, len_bits_low, NULL);
133 if (maphandle == 0) {
138 ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
140 DWORD dwLastErr = GetLastError();
141 if (dwLastErr == ERROR_MAPPED_ALIGNMENT)
145 CloseHandle(maphandle);
149 mm = (MemMap *)malloc(sizeof(MemMap));
153 mm->fhandle = fhandle;
154 mm->maphandle = maphandle;
156 mmap_addtail(mmapbase, mm);
161 /* munmap for windows */
162 intptr_t munmap(void *ptr, size_t UNUSED(size))
164 MemMap *mm = mmap_findlink(mmapbase, ptr);
169 UnmapViewOfFile(mm->mmap);
170 CloseHandle(mm->maphandle);
171 CloseHandle(mm->fhandle);
172 mmap_remlink(mmapbase, mm);
177 /* --------------------------------------------------------------------- */
178 /* local functions */
179 /* --------------------------------------------------------------------- */
181 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
183 struct mmapLink *link = vlink;
187 if (listbase == NULL)
191 link->prev = listbase->last;
194 ((struct mmapLink *)listbase->last)->next = link;
195 if (listbase->first == NULL)
196 listbase->first = link;
197 listbase->last = link;
200 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
202 struct mmapLink *link = vlink;
206 if (listbase == NULL)
210 link->next->prev = link->prev;
212 link->prev->next = link->next;
214 if (listbase->last == link)
215 listbase->last = link->prev;
216 if (listbase->first == link)
217 listbase->first = link->next;
220 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
226 if (listbase == NULL)
229 mm = (MemMap *)listbase->first;
231 if (mm->mmap == ptr) {
239 static int mmap_get_prot_flags(int flags)
241 int prot = PAGE_NOACCESS;
243 if ((flags & PROT_READ) == PROT_READ) {
244 if ((flags & PROT_WRITE) == PROT_WRITE) {
245 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
248 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
251 else if ((flags & PROT_WRITE) == PROT_WRITE) {
252 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
254 else if ((flags & PROT_EXEC) == PROT_EXEC) {
255 prot = PAGE_EXECUTE_READ;
260 static int mmap_get_access_flags(int flags)
264 if ((flags & PROT_READ) == PROT_READ) {
265 if ((flags & PROT_WRITE) == PROT_WRITE) {
266 access = FILE_MAP_WRITE;
269 access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
272 else if ((flags & PROT_WRITE) == PROT_WRITE) {
273 access = FILE_MAP_COPY;
275 else if ((flags & PROT_EXEC) == PROT_EXEC) {
276 access = FILE_MAP_EXECUTE;