Update Haiku support (#15674)
[mono-project.git] / mono / utils / mono-mmap-wasm.c
blob344efa219248dd42f62a20a26264546525658340
2 #include <config.h>
4 #ifdef HOST_WASM
6 #include <sys/types.h>
7 #if HAVE_SYS_STAT_H
8 #include <sys/stat.h>
9 #endif
10 #if HAVE_SYS_MMAN_H
11 #include <sys/mman.h>
12 #endif
13 #ifdef HAVE_SYS_SYSCTL_H
14 #include <sys/sysctl.h>
15 #endif
16 #ifdef HAVE_SIGNAL_H
17 #include <signal.h>
18 #endif
19 #include <fcntl.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <errno.h>
25 #include "mono-mmap.h"
26 #include "mono-mmap-internals.h"
27 #include "mono-proclib.h"
28 #include <mono/utils/mono-threads.h>
29 #include <mono/utils/atomic.h>
30 #include <mono/utils/mono-counters.h>
32 #define BEGIN_CRITICAL_SECTION do { \
33 MonoThreadInfo *__info = mono_thread_info_current_unchecked (); \
34 if (__info) __info->inside_critical_region = TRUE; \
36 #define END_CRITICAL_SECTION \
37 if (__info) __info->inside_critical_region = FALSE; \
38 } while (0) \
40 static void* malloced_shared_area = NULL;
42 int
43 mono_pagesize (void)
45 static int saved_pagesize = 0;
47 if (saved_pagesize)
48 return saved_pagesize;
50 // Prefer sysconf () as it's signal safe.
51 #if defined (HAVE_SYSCONF) && defined (_SC_PAGESIZE)
52 saved_pagesize = sysconf (_SC_PAGESIZE);
53 #else
54 saved_pagesize = getpagesize ();
55 #endif
57 return saved_pagesize;
60 int
61 mono_valloc_granule (void)
63 return mono_pagesize ();
66 static int
67 prot_from_flags (int flags)
69 int prot = PROT_NONE;
70 /* translate the protection bits */
71 if (flags & MONO_MMAP_READ)
72 prot |= PROT_READ;
73 if (flags & MONO_MMAP_WRITE)
74 prot |= PROT_WRITE;
75 if (flags & MONO_MMAP_EXEC)
76 prot |= PROT_EXEC;
77 return prot;
80 /**
81 * mono_setmmapjit:
82 * \param flag indicating whether to enable or disable the use of MAP_JIT in mmap
84 * Call this method to enable or disable the use of MAP_JIT to create the pages
85 * for the JIT to use. This is only needed for scenarios where Mono is bundled
86 * as an App in MacOS
88 void
89 mono_setmmapjit (int flag)
91 /* Ignored on HOST_WASM */
94 void*
95 mono_valloc (void *addr, size_t size, int flags, MonoMemAccountType type)
97 void *ptr;
98 int mflags = 0;
99 int prot = prot_from_flags (flags);
101 if (!mono_valloc_can_alloc (size))
102 return NULL;
104 if (size == 0)
105 /* emscripten throws an exception on 0 length */
106 return NULL;
108 mflags |= MAP_ANONYMOUS;
109 mflags |= MAP_PRIVATE;
111 BEGIN_CRITICAL_SECTION;
112 ptr = mmap (addr, size, prot, mflags, -1, 0);
113 END_CRITICAL_SECTION;
115 if (ptr == MAP_FAILED)
116 return NULL;
118 mono_account_mem (type, (ssize_t)size);
120 return ptr;
123 static GHashTable *valloc_hash;
125 typedef struct {
126 void *addr;
127 int size;
128 } VallocInfo;
130 void*
131 mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountType type)
133 /* Allocate twice the memory to be able to put the block on an aligned address */
134 char *mem = (char *) mono_valloc (NULL, size + alignment, flags, type);
135 char *aligned;
137 if (!mem)
138 return NULL;
140 aligned = mono_aligned_address (mem, size, alignment);
142 /* The mmap implementation in emscripten cannot unmap parts of regions */
143 /* Free the other two parts in when 'aligned' is freed */
144 // FIXME: This doubles the memory usage
145 if (!valloc_hash)
146 valloc_hash = g_hash_table_new (NULL, NULL);
147 VallocInfo *info = g_new0 (VallocInfo, 1);
148 info->addr = mem;
149 info->size = size + alignment;
150 g_hash_table_insert (valloc_hash, aligned, info);
152 return aligned;
156 mono_vfree (void *addr, size_t length, MonoMemAccountType type)
158 VallocInfo *info = valloc_hash ? g_hash_table_lookup (valloc_hash, addr) : NULL;
159 int res;
161 if (info) {
163 * We are passed the aligned address in the middle of the mapping allocated by
164 * mono_valloc_align (), free the original mapping.
166 BEGIN_CRITICAL_SECTION;
167 res = munmap (info->addr, info->size);
168 END_CRITICAL_SECTION;
169 g_free (info);
170 g_hash_table_remove (valloc_hash, info);
171 } else {
172 BEGIN_CRITICAL_SECTION;
173 res = munmap (addr, length);
174 END_CRITICAL_SECTION;
177 mono_account_mem (type, -(ssize_t)length);
179 return 0;
182 void*
183 mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
185 void *ptr;
186 int mflags = 0;
187 int prot = prot_from_flags (flags);
188 /* translate the flags */
189 if (flags & MONO_MMAP_PRIVATE)
190 mflags |= MAP_PRIVATE;
191 if (flags & MONO_MMAP_SHARED)
192 mflags |= MAP_SHARED;
193 if (flags & MONO_MMAP_FIXED)
194 mflags |= MAP_FIXED;
195 if (flags & MONO_MMAP_32BIT)
196 mflags |= MAP_32BIT;
198 if (length == 0)
199 /* emscripten throws an exception on 0 length */
200 return NULL;
202 BEGIN_CRITICAL_SECTION;
203 ptr = mmap (0, length, prot, mflags, fd, offset);
204 END_CRITICAL_SECTION;
205 if (ptr == MAP_FAILED)
206 return NULL;
207 *ret_handle = (void*)length;
208 return ptr;
211 void*
212 mono_file_map_error (size_t length, int flags, int fd, guint64 offset, void **ret_handle,
213 const char *filepath, char **error_message)
215 return mono_file_map (length, flags, fd, offset, ret_handle);
219 mono_file_unmap (void *addr, void *handle)
221 int res;
223 BEGIN_CRITICAL_SECTION;
224 res = munmap (addr, (size_t)handle);
225 END_CRITICAL_SECTION;
227 return res;
231 mono_mprotect (void *addr, size_t length, int flags)
233 return 0;
236 void*
237 mono_shared_area (void)
239 if (!malloced_shared_area)
240 malloced_shared_area = mono_malloc_shared_area (getpid ());
241 /* get the pid here */
242 return malloced_shared_area;
245 void
246 mono_shared_area_remove (void)
248 if (malloced_shared_area)
249 g_free (malloced_shared_area);
250 malloced_shared_area = NULL;
253 void*
254 mono_shared_area_for_pid (void *pid)
256 return NULL;
259 void
260 mono_shared_area_unload (void *area)
265 mono_shared_area_instances (void **array, int count)
267 return 0;
270 #endif