4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2008 Blender Foundation.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): Andrea Weikert.
27 * ***** END GPL LICENSE BLOCK *****
35 #include <sys/types.h>
40 #ifndef FILE_MAP_EXECUTE
41 //not defined in earlier versions of the Platform SDK (before February 2003)
42 #define FILE_MAP_EXECUTE 0x0020
45 /* --------------------------------------------------------------------- */
46 /* local storage definitions */
47 /* --------------------------------------------------------------------- */
48 /* all memory mapped chunks are put in linked lists */
49 typedef struct mmapLink
51 struct mmapLink *next,*prev;
54 typedef struct mmapListBase
59 typedef struct MemMap {
60 struct MemMap *next,*prev;
66 /* --------------------------------------------------------------------- */
68 /* --------------------------------------------------------------------- */
70 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink);
71 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink);
72 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr);
74 static int mmap_get_prot_flags (int flags);
75 static int mmap_get_access_flags (int flags);
77 /* --------------------------------------------------------------------- */
79 /* --------------------------------------------------------------------- */
80 volatile static struct mmapListBase _mmapbase;
81 volatile static struct mmapListBase *mmapbase = &_mmapbase;
84 /* --------------------------------------------------------------------- */
86 /* --------------------------------------------------------------------- */
88 /* mmap for windows */
89 void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset)
91 HANDLE fhandle = INVALID_HANDLE_VALUE;
93 int prot_flags = mmap_get_prot_flags(prot);
94 int access_flags = mmap_get_access_flags(prot);
98 if ( flags & MAP_FIXED ) {
110 fhandle = (HANDLE) _get_osfhandle (fd);
112 if ( fhandle == INVALID_HANDLE_VALUE ) {
113 if (!(flags & MAP_ANONYMOUS)) {
118 if ( !DuplicateHandle( GetCurrentProcess(), fhandle, GetCurrentProcess(),
119 &fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
124 maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
125 if ( maphandle == 0 ) {
130 ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
132 DWORD dwLastErr = GetLastError();
133 if ( dwLastErr == ERROR_MAPPED_ALIGNMENT )
137 CloseHandle(maphandle);
141 mm= (MemMap *)malloc(sizeof(MemMap));
145 mm->fhandle = fhandle;
146 mm->maphandle = maphandle;
148 mmap_addtail(mmapbase, mm);
153 /* munmap for windows */
154 long munmap(void *ptr, long size)
156 MemMap *mm = mmap_findlink(mmapbase, ptr);
161 UnmapViewOfFile( mm->mmap );
162 CloseHandle( mm->maphandle );
163 CloseHandle( mm->fhandle);
164 mmap_remlink(mmapbase, mm);
168 /* --------------------------------------------------------------------- */
169 /* local functions */
170 /* --------------------------------------------------------------------- */
172 static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
174 struct mmapLink *link= vlink;
176 if (link == 0) return;
177 if (listbase == 0) return;
180 link->prev = listbase->last;
182 if (listbase->last) ((struct mmapLink *)listbase->last)->next = link;
183 if (listbase->first == 0) listbase->first = link;
184 listbase->last = link;
187 static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
189 struct mmapLink *link= vlink;
191 if (link == 0) return;
192 if (listbase == 0) return;
194 if (link->next) link->next->prev = link->prev;
195 if (link->prev) link->prev->next = link->next;
197 if (listbase->last == link) listbase->last = link->prev;
198 if (listbase->first == link) listbase->first = link->next;
201 static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
203 MemMap *mmap_ptr = (MemMap*)ptr;
206 if (ptr == 0) return NULL;
207 if (listbase == 0) return NULL;
209 mm = (MemMap *)listbase->first;
211 if (mm->mmap == ptr) {
219 static int mmap_get_prot_flags (int flags)
221 int prot = PAGE_NOACCESS;
223 if ( ( flags & PROT_READ ) == PROT_READ ) {
224 if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
225 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
227 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
229 } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
230 prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
231 } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
232 prot = PAGE_EXECUTE_READ;
237 static int mmap_get_access_flags (int flags)
241 if ( ( flags & PROT_READ ) == PROT_READ ) {
242 if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
243 access = FILE_MAP_WRITE;
245 access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
247 } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
248 access = FILE_MAP_COPY;
249 } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
250 access = FILE_MAP_EXECUTE;