use lowercase for cmake builtin names and macros, remove contents in else() and endif...
[blender.git] / intern / guardedalloc / intern / mmap_win.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Andrea Weikert.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29  
30 #if defined(WIN32)
31
32 #include <windows.h>
33 #include <errno.h>
34 #include <io.h>
35 #include <sys/types.h>
36 #include <stdio.h>
37
38 #include "mmap_win.h"
39
40 #ifndef FILE_MAP_EXECUTE
41 //not defined in earlier versions of the Platform  SDK (before February 2003)
42 #define FILE_MAP_EXECUTE 0x0020
43 #endif
44
45 /* copied from BKE_utildefines.h ugh */
46 #ifdef __GNUC__
47 #  define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
48 #else
49 #  define UNUSED(x) x
50 #endif
51
52 /* --------------------------------------------------------------------- */
53 /* local storage definitions                                                    */
54 /* --------------------------------------------------------------------- */
55 /* all memory mapped chunks are put in linked lists */
56 typedef struct mmapLink
57 {
58         struct mmapLink *next,*prev;
59 } mmapLink;
60
61 typedef struct mmapListBase 
62 {
63         void *first, *last;
64 } mmapListBase;
65
66 typedef struct MemMap {
67         struct MemMap *next,*prev;
68         void *mmap;
69         HANDLE fhandle;
70         HANDLE maphandle;
71 } MemMap;
72
73 /* --------------------------------------------------------------------- */
74 /* local functions                                                       */
75 /* --------------------------------------------------------------------- */
76
77 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink);
78 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink);
79 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr);
80
81 static int mmap_get_prot_flags (int flags);
82 static int mmap_get_access_flags (int flags);
83
84 /* --------------------------------------------------------------------- */
85 /* vars                                                                  */
86 /* --------------------------------------------------------------------- */
87 volatile static struct mmapListBase _mmapbase;
88 volatile static struct mmapListBase *mmapbase = &_mmapbase;
89
90
91 /* --------------------------------------------------------------------- */
92 /* implementation                                                        */
93 /* --------------------------------------------------------------------- */
94
95 /* mmap for windows */
96 void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t offset)
97 {
98         HANDLE fhandle = INVALID_HANDLE_VALUE;
99         HANDLE maphandle;
100         int prot_flags = mmap_get_prot_flags(prot);
101         int access_flags = mmap_get_access_flags(prot);
102         MemMap *mm = NULL;
103         void *ptr = NULL;
104
105         if ( flags & MAP_FIXED ) {
106                 return MAP_FAILED;
107         }
108
109         /*
110         if ( fd == -1 ) {
111                 _set_errno( EBADF );
112         return MAP_FAILED;
113         }
114         */
115
116         if ( fd != -1 ) {
117                 fhandle = (HANDLE) _get_osfhandle (fd);
118         }
119         if ( fhandle == INVALID_HANDLE_VALUE ) {
120                 if (!(flags & MAP_ANONYMOUS)) {
121                         errno = EBADF;
122                         return MAP_FAILED;
123                 }
124         } else {
125                 if ( !DuplicateHandle( GetCurrentProcess(), fhandle, GetCurrentProcess(),
126                                                         &fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
127                         return MAP_FAILED;
128                 }
129         }
130
131         maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
132         if ( maphandle == 0 ) {
133         errno = EBADF;
134                 return MAP_FAILED;
135     }
136
137         ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
138         if ( ptr == NULL ) {
139                 DWORD dwLastErr = GetLastError();
140                 if ( dwLastErr == ERROR_MAPPED_ALIGNMENT )
141                         errno=EINVAL;
142                 else
143                         errno=EACCES;
144                 CloseHandle(maphandle);
145                 return MAP_FAILED;
146         }
147
148         mm= (MemMap *)malloc(sizeof(MemMap));
149         if (!mm) {
150                 errno=ENOMEM;
151         }
152         mm->fhandle = fhandle;
153         mm->maphandle = maphandle;
154         mm->mmap = ptr;
155         mmap_addtail(mmapbase, mm);
156
157     return ptr;
158 }
159
160 /* munmap for windows */
161 intptr_t munmap(void *ptr, intptr_t UNUSED(size))
162 {
163         MemMap *mm = mmap_findlink(mmapbase, ptr);
164         if (!mm) {
165                 errno=EINVAL;
166         return -1; 
167         }
168         UnmapViewOfFile( mm->mmap );
169         CloseHandle( mm->maphandle );
170         CloseHandle( mm->fhandle);
171         mmap_remlink(mmapbase, mm);
172         free(mm);
173     return 0;
174 }
175
176 /* --------------------------------------------------------------------- */
177 /* local functions                                                       */
178 /* --------------------------------------------------------------------- */
179
180 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
181 {
182         struct mmapLink *link= vlink;
183
184         if (link == 0) return;
185         if (listbase == 0) return;
186
187         link->next = 0;
188         link->prev = listbase->last;
189
190         if (listbase->last) ((struct mmapLink *)listbase->last)->next = link;
191         if (listbase->first == 0) listbase->first = link;
192         listbase->last = link;
193 }
194
195 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
196 {
197         struct mmapLink *link= vlink;
198
199         if (link == 0) return;
200         if (listbase == 0) return;
201
202         if (link->next) link->next->prev = link->prev;
203         if (link->prev) link->prev->next = link->next;
204
205         if (listbase->last == link) listbase->last = link->prev;
206         if (listbase->first == link) listbase->first = link->next;
207 }
208
209 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
210 {
211         MemMap *mm;
212
213         if (ptr == 0) return NULL;
214         if (listbase == 0) return NULL;
215         
216         mm = (MemMap *)listbase->first;
217         while (mm) {
218                 if (mm->mmap == ptr) {
219                         return mm;
220                 }
221                 mm = mm->next;
222         }
223         return NULL;
224 }
225
226 static int mmap_get_prot_flags (int flags)
227 {
228         int prot = PAGE_NOACCESS;
229
230         if ( ( flags & PROT_READ ) == PROT_READ ) {
231         if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
232             prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
233                 } else {
234                         prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
235                 }
236     } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
237                 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
238     } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
239         prot = PAGE_EXECUTE_READ;
240     }
241         return prot;
242 }
243
244 static int mmap_get_access_flags (int flags)
245 {
246         int access = 0;
247
248         if ( ( flags & PROT_READ ) == PROT_READ ) {
249         if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
250             access = FILE_MAP_WRITE;
251                 } else {
252                         access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
253                 }
254     } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
255                 access = FILE_MAP_COPY;
256     } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
257         access = FILE_MAP_EXECUTE;
258     }
259         return access;
260 }
261
262
263 #endif // WIN32
264
265
266
267
268