diff options
author | Andrea Weikert <elubie@gmx.net> | 2008-04-29 22:41:34 +0400 |
---|---|---|
committer | Andrea Weikert <elubie@gmx.net> | 2008-04-29 22:41:34 +0400 |
commit | e7c3ff64584a68e39c7273026b6504e2fa4ced44 (patch) | |
tree | f5c50a47f5711d9de94c8cccccf3fb983bd5354c /intern | |
parent | 391bd70d42017c341a841a86da82fa1d06a381e0 (diff) |
== mmap for win32 ==
replacement for mmap/munmap on Windows.
Implemented using CreateFileMapping/MapViewOfFile.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/guardedalloc/intern/mallocn.c | 9 | ||||
-rw-r--r-- | intern/guardedalloc/intern/mmap_win.c | 261 | ||||
-rw-r--r-- | intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj | 10 | ||||
-rw-r--r-- | intern/guardedalloc/mmap_win.h | 52 |
4 files changed, 329 insertions, 3 deletions
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index f95d9aa418a..25f2fd8d269 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -38,7 +38,10 @@ #include <stdarg.h> /* mmap exception */ -#if defined(AMIGA) || defined(__BeOS) || defined(WIN32) +#if defined(AMIGA) || defined(__BeOS) +#elif defined(WIN32) +#include <sys/types.h> +#include "mmap_win.h" #else #include <sys/types.h> #include <sys/mman.h> @@ -289,7 +292,7 @@ void *MEM_callocN(unsigned int len, const char *str) /* note; mmap returns zero'd memory */ void *MEM_mapallocN(unsigned int len, const char *str) { -#if defined(AMIGA) || defined(__BeOS) || defined(WIN32) +#if defined(AMIGA) || defined(__BeOS) return MEM_callocN(len, str); #else MemHead *memh; @@ -586,7 +589,7 @@ static void rem_memblock(MemHead *memh) totblock--; mem_in_use -= memh->len; -#if defined(AMIGA) || defined(__BeOS) || defined(WIN32) +#if defined(AMIGA) || defined(__BeOS) free(memh); #else diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c new file mode 100644 index 00000000000..cc31cf5174e --- /dev/null +++ b/intern/guardedalloc/intern/mmap_win.c @@ -0,0 +1,261 @@ +/** + * $Id: $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Andrea Weikert. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#if defined(WIN32) + +#include <windows.h> +#include <errno.h> +#include <io.h> +#include <sys/types.h> +#include <stdio.h> + +#include "mmap_win.h" + +#ifndef FILE_MAP_EXECUTE +//not defined in earlier versions of the Platform SDK (before February 2003) +#define FILE_MAP_EXECUTE 0x0020 +#endif + +/* --------------------------------------------------------------------- */ +/* local storage definitions */ +/* --------------------------------------------------------------------- */ +/* all memory mapped chunks are put in linked lists */ +typedef struct mmapLink +{ + struct mmapLink *next,*prev; +} mmapLink; + +typedef struct mmapListBase +{ + void *first, *last; +} mmapListBase; + +typedef struct MemMap { + struct MemMap *next,*prev; + void *mmap; + HANDLE fhandle; + HANDLE maphandle; +} MemMap; + +/* --------------------------------------------------------------------- */ +/* local functions */ +/* --------------------------------------------------------------------- */ + +static void mmap_addtail(volatile mmapListBase *listbase, void *vlink); +static void mmap_remlink(volatile mmapListBase *listbase, void *vlink); +static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr); + +static int mmap_get_prot_flags (int flags); +static int mmap_get_access_flags (int flags); + +/* --------------------------------------------------------------------- */ +/* vars */ +/* --------------------------------------------------------------------- */ +volatile static struct mmapListBase _mmapbase; +volatile static struct mmapListBase *mmapbase = &_mmapbase; + + +/* --------------------------------------------------------------------- */ +/* implementation */ +/* --------------------------------------------------------------------- */ + +/* mmap for windows */ +void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset) +{ + HANDLE fhandle = INVALID_HANDLE_VALUE; + HANDLE maphandle; + int prot_flags = mmap_get_prot_flags(prot); + int access_flags = mmap_get_access_flags(prot); + MemMap *mm = NULL; + void *ptr = NULL; + + if ( flags & MAP_FIXED ) { + return MAP_FAILED; + } + + /* + if ( fd == -1 ) { + _set_errno( EBADF ); + return MAP_FAILED; + } + */ + + if ( fd != -1 ) { + fhandle = (HANDLE) _get_osfhandle (fd); + } + if ( fhandle == INVALID_HANDLE_VALUE ) { + if (!(flags & MAP_ANONYMOUS)) { + errno = EBADF; + return MAP_FAILED; + } + } else { + if ( !DuplicateHandle( GetCurrentProcess(), fhandle, GetCurrentProcess(), + &fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { + return MAP_FAILED; + } + } + + maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL); + if ( maphandle == 0 ) { + errno = EBADF; + return MAP_FAILED; + } + + ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0); + if ( ptr == NULL ) { + DWORD dwLastErr = GetLastError(); + if ( dwLastErr == ERROR_MAPPED_ALIGNMENT ) + errno=EINVAL; + else + errno=EACCES; + CloseHandle(maphandle); + return MAP_FAILED; + } + + mm= (MemMap *)malloc(sizeof(MemMap)); + if (!mm) { + errno=ENOMEM; + } + mm->fhandle = fhandle; + mm->maphandle = maphandle; + mm->mmap = ptr; + mmap_addtail(mmapbase, mm); + + return ptr; +} + +/* munmap for windows */ +long munmap(void *ptr, long size) +{ + MemMap *mm = mmap_findlink(mmapbase, ptr); + if (!mm) { + errno=EINVAL; + return -1; + } + UnmapViewOfFile( mm->mmap ); + CloseHandle( mm->maphandle ); + CloseHandle( mm->fhandle); + mmap_remlink(mmapbase, mm); + return 0; +} + +/* --------------------------------------------------------------------- */ +/* local functions */ +/* --------------------------------------------------------------------- */ + +static void mmap_addtail(volatile mmapListBase *listbase, void *vlink) +{ + struct mmapLink *link= vlink; + + if (link == 0) return; + if (listbase == 0) return; + + link->next = 0; + link->prev = listbase->last; + + if (listbase->last) ((struct mmapLink *)listbase->last)->next = link; + if (listbase->first == 0) listbase->first = link; + listbase->last = link; +} + +static void mmap_remlink(volatile mmapListBase *listbase, void *vlink) +{ + struct mmapLink *link= vlink; + + if (link == 0) return; + if (listbase == 0) return; + + if (link->next) link->next->prev = link->prev; + if (link->prev) link->prev->next = link->next; + + if (listbase->last == link) listbase->last = link->prev; + if (listbase->first == link) listbase->first = link->next; +} + +static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr) +{ + MemMap *mmap_ptr = (MemMap*)ptr; + MemMap *mm; + + if (ptr == 0) return NULL; + if (listbase == 0) return NULL; + + mm = (MemMap *)listbase->first; + while (mm) { + if (mm->mmap == ptr) { + return mm; + } + mm = mm->next; + } + return NULL; +} + +static int mmap_get_prot_flags (int flags) +{ + int prot = PAGE_NOACCESS; + + if ( ( flags & PROT_READ ) == PROT_READ ) { + if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { + prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; + } else { + prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY; + } + } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { + prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY; + } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) { + prot = PAGE_EXECUTE_READ; + } + return prot; +} + +static int mmap_get_access_flags (int flags) +{ + int access = 0; + + if ( ( flags & PROT_READ ) == PROT_READ ) { + if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { + access = FILE_MAP_WRITE; + } else { + access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ; + } + } else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) { + access = FILE_MAP_COPY; + } else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) { + access = FILE_MAP_EXECUTE; + } + return access; +} + + +#endif // WIN32 + + + + + diff --git a/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj b/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj index cb3490716fa..40e88511d5d 100644 --- a/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj +++ b/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj @@ -251,6 +251,9 @@ ECHO Done <File RelativePath="..\..\intern\mallocn.c"> </File> + <File + RelativePath="..\..\intern\mmap_win.c"> + </File> </Filter> <Filter Name="Header Files" @@ -261,6 +264,13 @@ ECHO Done <File RelativePath="..\..\MEM_guardedalloc.h"> </File> + <File + RelativePath="..\..\mmap_win.h"> + </File> + </Filter> + <Filter + Name="intern" + Filter=""> </Filter> </Filter> </Files> diff --git a/intern/guardedalloc/mmap_win.h b/intern/guardedalloc/mmap_win.h new file mode 100644 index 00000000000..f83a2d64b18 --- /dev/null +++ b/intern/guardedalloc/mmap_win.h @@ -0,0 +1,52 @@ +/** + * $Id: $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Andrea Weikert. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef MMAP_WIN_H +#define MMAP_WIN_H + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xF +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED ((void *)-1) + +void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset); +long munmap(void *ptr, long size); + +#endif + |