Author: lupus
Date: 2006-12-11 09:09:22 -0500 (Mon, 11 Dec 2006)
New Revision: 69326

Added:
   trunk/mono/mono/utils/mono-mmap.c
   trunk/mono/mono/utils/mono-mmap.h
Modified:
   trunk/mono/mono/utils/ChangeLog
   trunk/mono/mono/utils/Makefile.am
Log:


Mon Dec 11 15:08:27 CET 2006 Paolo Molaro <[EMAIL PROTECTED]>

        * mono-mmap.c, mono-mmap.h, Makefile.am: introduced mmap-like API.



Modified: trunk/mono/mono/utils/ChangeLog
===================================================================
--- trunk/mono/mono/utils/ChangeLog     2006-12-11 13:57:59 UTC (rev 69325)
+++ trunk/mono/mono/utils/ChangeLog     2006-12-11 14:09:22 UTC (rev 69326)
@@ -1,4 +1,8 @@
 
+Mon Dec 11 15:08:27 CET 2006 Paolo Molaro <[EMAIL PROTECTED]>
+
+       * mono-mmap.c, mono-mmap.h, Makefile.am: introduced mmap-like API.
+
 Mon Nov 27 16:03:58 CET 2006 Paolo Molaro <[EMAIL PROTECTED]>
 
        * strtod.c: fix, again, 64 bit issues.

Modified: trunk/mono/mono/utils/Makefile.am
===================================================================
--- trunk/mono/mono/utils/Makefile.am   2006-12-11 13:57:59 UTC (rev 69325)
+++ trunk/mono/mono/utils/Makefile.am   2006-12-11 14:09:22 UTC (rev 69326)
@@ -18,6 +18,8 @@
        mono-compiler.h \
        monobitset.c    \
        mono-math.c  \
+       mono-mmap.c  \
+       mono-mmap.h  \
        strtod.h        \
        strtod.c        \
        strenc.h        \

Added: trunk/mono/mono/utils/mono-mmap.c
===================================================================
--- trunk/mono/mono/utils/mono-mmap.c   2006-12-11 13:57:59 UTC (rev 69325)
+++ trunk/mono/mono/utils/mono-mmap.c   2006-12-11 14:09:22 UTC (rev 69326)
@@ -0,0 +1,373 @@
+#include "config.h"
+
+#ifdef PLATFORM_WIN32
+#include <windows.h>
+#include <io.h>
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#endif
+
+#include "mono-mmap.h"
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#ifndef MAP_32BIT
+#define MAP_32BIT 0
+#endif
+
+#ifdef PLATFORM_WIN32
+
+int
+mono_pagesize (void)
+{
+       static int saved_pagesize = 0;
+       if (saved_pagesize)
+               return saved_pagesize;
+       SYSTEM_INFO info;
+       GetSystemInfo (&info);
+       saved_pagesize = info.dwAllocationGranularity;
+       return saved_pagesize;
+}
+
+static int
+prot_from_flags (int flags)
+{
+       int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
+       switch (prot) {
+       case 0: prot = PAGE_NOACCESS; break;
+       case MONO_MMAP_READ: prot = PAGE_READONLY; break;
+       case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
+       case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
+       case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = 
PAGE_EXECUTE_READWRITE; break;
+       case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
+       case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; 
break;
+       case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
+       default:
+               g_assert_not_reached ();
+       }
+       return prot;
+}
+
+void*
+mono_valloc (void *addr, size_t length, int flags)
+{
+       void *ptr;
+       int mflags = MEM_COMMIT;
+       int prot = prot_from_flags (flags);
+       /* translate the flags */
+
+       ptr = VirtualAlloc (addr, length, mflags, prot);
+       return ptr;
+}
+
+int
+mono_vfree (void *addr, size_t length)
+{
+       return VirtualFree (addr, length, MEM_RELEASE) == 0;
+}
+
+void*
+mono_file_map (size_t length, int flags, int fd, off_t offset, void 
**ret_handle)
+{
+       void *ptr;
+       int mflags = 0;
+       HANDLE file, mapping;
+       int prot = prot_from_flags (flags);
+       /* translate the flags */
+       /*if (flags & MONO_MMAP_PRIVATE)
+               mflags |= MAP_PRIVATE;
+       if (flags & MONO_MMAP_SHARED)
+               mflags |= MAP_SHARED;
+       if (flags & MONO_MMAP_ANON)
+               mflags |= MAP_ANONYMOUS;
+       if (flags & MONO_MMAP_FIXED)
+               mflags |= MAP_FIXED;
+       if (flags & MONO_MMAP_32BIT)
+               mflags |= MAP_32BIT;*/
+
+       mflags = FILE_MAP_READ;
+       if (flags & MONO_MMAP_WRITE)
+               mflags = FILE_MAP_COPY;
+
+       file = (HANDLE) _get_osfhandle (fd);
+       mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
+       if (mapping == NULL)
+               return NULL;
+       ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
+       if (ptr == NULL) {
+               CloseHandle (mapping);
+               return NULL;
+       }
+       *ret_handle = (void*)mapping;
+       return ptr;
+}
+
+int
+mono_file_unmap (void *addr, void *handle)
+{
+       UnmapViewOfFile (addr);
+       CloseHandle ((HANDLE)handle);
+       return 0;
+}
+
+int
+mono_mprotect (void *addr, size_t length, int flags)
+{
+       DWORD oldprot;
+       int prot = prot_from_flags (flags);
+
+       if (flags & MONO_MMAP_DISCARD) {
+               VirtualFree (addr, length, MEM_DECOMMIT);
+               VirtualAlloc (addr, length, MEM_COMMIT, prot);
+               return 0;
+       }
+       return VirtualProtect (addr, length, prot, &oldprot) == 0;
+}
+
+#elif defined(HAVE_MMAP)
+
+/**
+ * mono_pagesize:
+ * Get the page size in use on the system. Addresses and sizes in the
+ * mono_mmap(), mono_munmap() and mono_mprotect() calls must be pagesize
+ * aligned.
+ *
+ * Returns: the page size in bytes.
+ */
+int
+mono_pagesize (void)
+{
+       static int saved_pagesize = 0;
+       if (saved_pagesize)
+               return saved_pagesize;
+       saved_pagesize = getpagesize ();
+       return saved_pagesize;
+}
+
+static int
+prot_from_flags (int flags)
+{
+       int prot = PROT_NONE;
+       /* translate the protection bits */
+       if (flags & MONO_MMAP_READ)
+               prot |= PROT_READ;
+       if (flags & MONO_MMAP_WRITE)
+               prot |= PROT_WRITE;
+       if (flags & MONO_MMAP_EXEC)
+               prot |= PROT_EXEC;
+       return prot;
+}
+
+/**
+ * mono_valloc:
+ * @addr: memory address
+ * @length: memory area size
+ * @flags: protection flags
+ *
+ * Allocates @length bytes of virtual memory with the @flags
+ * protection. @addr can be a preferred memory address or a
+ * mandatory one if MONO_MMAP_FIXED is set in @flags.
+ * @addr must be pagesize aligned and can be NULL.
+ * @length must be a multiple of pagesize.
+ *
+ * Returns: NULL on failure, the address of the memory area otherwise
+ */
+void*
+mono_valloc (void *addr, size_t length, int flags)
+{
+       void *ptr;
+       int mflags = 0;
+       int prot = prot_from_flags (flags);
+       /* translate the flags */
+       if (flags & MONO_MMAP_FIXED)
+               mflags |= MAP_FIXED;
+       if (flags & MONO_MMAP_32BIT)
+               mflags |= MAP_32BIT;
+
+       mflags |= MAP_ANONYMOUS;
+       mflags |= MAP_PRIVATE;
+
+       ptr = mmap (addr, length, prot, mflags, -1, 0);
+       if (ptr == (void*)-1) {
+               int fd = open ("/dev/zero", O_RDONLY);
+               if (fd != -1) {
+                       ptr = mmap (addr, length, prot, mflags, fd, 0);
+                       close (fd);
+               }
+               if (ptr == (void*)-1)
+                       return NULL;
+       }
+       return ptr;
+}
+
+/**
+ * mono_vfree:
+ * @addr: memory address returned by mono_valloc ()
+ * @length: size of memory area
+ *
+ * Remove the memory mapping at the address @addr.
+ *
+ * Returns: 0 on success.
+ */
+int
+mono_vfree (void *addr, size_t length)
+{
+       return munmap (addr, length);
+}
+
+/**
+ * mono_file_map:
+ * @length: size of data to map
+ * @flags: protection flags
+ * @fd: file descriptor
+ * @offset: offset in the file
+ * @ret_handle: pointer to storage for returning a handle for the map
+ *
+ * Map the area of the file pointed to by the file descriptor @fd, at offset
+ * @offset and of size @length in memory according to the protection flags
+ * @flags.
+ * @offset and @length must be multiples of the page size.
+ * @ret_handle must point to a void*: this value must be used when unmapping
+ * the memory area using mono_file_unmap ().
+ *
+ */
+void*
+mono_file_map (size_t length, int flags, int fd, off_t offset, void 
**ret_handle)
+{
+       void *ptr;
+       int mflags = 0;
+       int prot = prot_from_flags (flags);
+       /* translate the flags */
+       if (flags & MONO_MMAP_PRIVATE)
+               mflags |= MAP_PRIVATE;
+       if (flags & MONO_MMAP_SHARED)
+               mflags |= MAP_SHARED;
+       if (flags & MONO_MMAP_FIXED)
+               mflags |= MAP_FIXED;
+       if (flags & MONO_MMAP_32BIT)
+               mflags |= MAP_32BIT;
+
+       ptr = mmap (0, length, prot, mflags, fd, offset);
+       if (ptr == (void*)-1)
+               return NULL;
+       *ret_handle = (void*)length;
+       return ptr;
+}
+
+/**
+ * mono_file_unmap:
+ * @addr: memory address returned by mono_file_map ()
+ * @handle: handle of memory map
+ *
+ * Remove the memory mapping at the address @addr.
+ * @handle must be the value returned in ret_handle by mono_file_map ().
+ *
+ * Returns: 0 on success.
+ */
+int
+mono_file_unmap (void *addr, void *handle)
+{
+       return munmap (addr, (size_t)handle);
+}
+
+/**
+ * mono_mprotect:
+ * @addr: memory address
+ * @length: size of memory area
+ * @flags: new protection flags
+ *
+ * Change the protection for the memory area at @addr for @length bytes
+ * to matche the supplied @flags.
+ * If @flags includes MON_MMAP_DISCARD the pages are discarded from memory
+ * and the area is cleared to zero.
+ * @addr must be aligned to the page size.
+ * @length must be a multiple of the page size.
+ *
+ * Returns: 0 on success.
+ */
+int
+mono_mprotect (void *addr, size_t length, int flags)
+{
+       int prot = prot_from_flags (flags);
+
+       if (flags & MONO_MMAP_DISCARD) {
+               /* on non-linux the pages are not guaranteed to be zeroed 
(*bsd, osx at least) */
+#ifdef __linux__
+               if (madvise (addr, length, MADV_DONTNEED))
+                       memset (addr, 0, length);
+#else
+               memset (addr, 0, length);
+               madvise (addr, length, MADV_DONTNEED);
+               madvise (addr, length, MADV_FREE);
+#endif
+       }
+       return mprotect (addr, length, prot);
+}
+
+#else
+
+/* dummy malloc-based implementation */
+int
+mono_pagesize (void)
+{
+       return 4096;
+}
+
+void*
+mono_valloc (void *addr, size_t length, int flags)
+{
+       return malloc (length);
+}
+
+int
+mono_vfree (void *addr, size_t length)
+{
+       free (addr);
+       return 0;
+}
+
+void*
+mono_file_map (size_t length, int flags, int fd, off_t offset, void 
**ret_handle)
+{
+       off_t cur_offset;
+       size_t bytes_read;
+       void *ptr = malloc (length);
+       if (!ptr)
+               return NULL;
+       cur_offset = lseek (fd, 0, SEEK_CUR);
+       if (lseek (fd, offset, SEEK_SET) != offset) {
+               free (ptr);
+               return NULL;
+       }
+       bytes_read = read (fd, ptr, length);
+       lseek (fd, cur_offset, SEEK_SET);
+       *ret_handle = NULL;
+       return ptr;
+}
+
+int
+mono_file_unmap (void *addr, void *handle)
+{
+       free (addr);
+       return 0;
+}
+
+int
+mono_mprotect (void *addr, size_t length, int flags)
+{
+       if (flags & MONO_MMAP_DISCARD) {
+               memset (addr, 0, length);
+       }
+       return 0;
+}
+
+#endif
+

Added: trunk/mono/mono/utils/mono-mmap.h
===================================================================
--- trunk/mono/mono/utils/mono-mmap.h   2006-12-11 13:57:59 UTC (rev 69325)
+++ trunk/mono/mono/utils/mono-mmap.h   2006-12-11 14:09:22 UTC (rev 69326)
@@ -0,0 +1,28 @@
+#ifndef __MONO_UTILS_MMAP_H__
+#define __MONO_UTILS_MMAP_H__
+
+enum {
+       /* protection */
+       MONO_MMAP_NONE = 0,
+       MONO_MMAP_READ    = 1 << 0,
+       MONO_MMAP_WRITE   = 1 << 1,
+       MONO_MMAP_EXEC    = 1 << 2,
+       /* make the OS discard the dirty data and fill with 0 */
+       MONO_MMAP_DISCARD = 1 << 3,
+       /* other flags (add commit, sync) */
+       MONO_MMAP_PRIVATE = 1 << 4,
+       MONO_MMAP_SHARED  = 1 << 5,
+       MONO_MMAP_ANON    = 1 << 6,
+       MONO_MMAP_FIXED   = 1 << 7,
+       MONO_MMAP_32BIT   = 1 << 8
+};
+
+int   mono_pagesize   (void);
+void* mono_valloc     (void *addr, size_t length, int flags);
+int   mono_vfree      (void *addr, size_t length);
+void* mono_file_map   (size_t length, int flags, int fd, off_t offset, void 
**ret_handle);
+int   mono_file_unmap (void *addr, void *handle);
+int   mono_mprotect   (void *addr, size_t length, int flags);
+
+#endif /* __MONO_UTILS_MMAP_H__ */
+

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to