2 * rawbuffer.c: Manages buffers that might have been mmapped or malloced
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc.
10 #if defined(PLATFORM_WIN32)
11 #define USE_WIN32_API 1
21 #include <sys/types.h>
23 #include "rawbuffer.h"
25 #include <mono/io-layer/io-layer.h>
27 #define ROUND_DOWN(VALUE,SIZE) ((VALUE) & ~((SIZE) - 1))
28 #define ROUND_UP(VALUE,SIZE) (ROUND_DOWN((VALUE) + (SIZE) - 1, (SIZE)))
29 #if SIZEOF_VOID_P == 8
30 #define UINTPTR_TYPE guint64
32 #define UINTPTR_TYPE guint32
35 static GHashTable *mmap_map = NULL;
36 static size_t alignment = 0;
37 static CRITICAL_SECTION mmap_mutex;
45 GetSystemInfo (&info);
46 alignment = info.dwAllocationGranularity;
48 alignment = getpagesize ();
53 mono_raw_buffer_load_malloc (int fd, int is_writable, guint32 base, size_t size)
57 ptr = g_malloc (size);
61 if (lseek (fd, base, 0) == (off_t) -1) {
71 mono_raw_buffer_free_malloc (void *base)
77 mono_raw_buffer_init (void)
79 InitializeCriticalSection (&mmap_mutex);
83 mmap_map = g_hash_table_new (g_direct_hash, g_direct_equal);
87 mono_raw_buffer_load_mmap (int fd, int is_writable, guint32 base, size_t size)
90 /* FileMapping implementation */
97 start = ROUND_DOWN (base, alignment);
101 prot = PAGE_WRITECOPY;
102 access = FILE_MAP_COPY;
105 prot = PAGE_READONLY;
106 access = FILE_MAP_READ;
109 file = (HANDLE) _get_osfhandle (fd);
110 mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
114 ptr = MapViewOfFile (mapping, access, 0, start, end - start);
116 CloseHandle (mapping);
120 EnterCriticalSection (&mmap_mutex);
121 g_hash_table_insert (mmap_map, ptr, GINT_TO_POINTER (mapping));
122 LeaveCriticalSection (&mmap_mutex);
124 return ((char *)ptr) + (base - start);
127 /* mmap implementation */
131 int prot = PROT_READ;
135 start = ROUND_DOWN (base, alignment);
136 end = ROUND_UP (base + size, alignment);
145 ptr = mmap (0, end - start, prot, flags, fd, start);
147 if (ptr == (void *) -1)
150 EnterCriticalSection (&mmap_mutex);
151 g_hash_table_insert (mmap_map, ptr, GINT_TO_POINTER (size));
152 LeaveCriticalSection (&mmap_mutex);
154 return ((char *)ptr) + (base - start);
159 mono_raw_buffer_free_mmap (void *base)
163 EnterCriticalSection (&mmap_mutex);
164 value = GPOINTER_TO_INT (g_hash_table_lookup (mmap_map, base));
165 LeaveCriticalSection (&mmap_mutex);
168 UnmapViewOfFile (base);
169 CloseHandle ((HANDLE) value);
171 munmap (base, value);
176 mono_raw_buffer_update_mmap (void *base, size_t size)
179 FlushViewOfFile (base, size);
181 msync (base, size, MS_SYNC);
186 mono_raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
190 ptr = mono_raw_buffer_load_mmap (fd, is_writable, base, size);
192 ptr = mono_raw_buffer_load_malloc (fd, is_writable, base, size);
198 mono_raw_buffer_update (void *buffer, size_t size)
203 mmap_base = (gpointer)(ROUND_DOWN ((UINTPTR_TYPE) (buffer), alignment));
205 EnterCriticalSection (&mmap_mutex);
206 exists = g_hash_table_lookup (mmap_map, mmap_base) != NULL;
207 LeaveCriticalSection (&mmap_mutex);
209 mono_raw_buffer_update_mmap (mmap_base, size);
213 mono_raw_buffer_free (void *buffer)
218 mmap_base = (gpointer)(ROUND_DOWN ((UINTPTR_TYPE) (buffer), alignment));
220 exists = g_hash_table_lookup (mmap_map, mmap_base) != NULL;
222 mono_raw_buffer_free_mmap (mmap_base);
224 mono_raw_buffer_free_malloc (buffer);