13 #ifdef HAVE_SYS_SYSCTL_H
14 #include <sys/sysctl.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; \
40 static void* malloced_shared_area = NULL;
45 static int saved_pagesize
= 0;
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
);
54 saved_pagesize
= getpagesize ();
57 return saved_pagesize
;
61 mono_valloc_granule (void)
63 return mono_pagesize ();
67 prot_from_flags (int flags
)
70 /* translate the protection bits */
71 if (flags
& MONO_MMAP_READ
)
73 if (flags
& MONO_MMAP_WRITE
)
75 if (flags
& MONO_MMAP_EXEC
)
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
89 mono_setmmapjit (int flag
)
91 /* Ignored on HOST_WASM */
95 mono_valloc (void *addr
, size_t size
, int flags
, MonoMemAccountType type
)
99 int prot
= prot_from_flags (flags
);
101 if (!mono_valloc_can_alloc (size
))
105 /* emscripten throws an exception on 0 length */
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
)
118 mono_account_mem (type
, (ssize_t
)size
);
123 static GHashTable
*valloc_hash
;
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
);
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
146 valloc_hash
= g_hash_table_new (NULL
, NULL
);
147 VallocInfo
*info
= g_new0 (VallocInfo
, 1);
149 info
->size
= size
+ alignment
;
150 g_hash_table_insert (valloc_hash
, aligned
, info
);
156 mono_vfree (void *addr
, size_t length
, MonoMemAccountType type
)
158 VallocInfo
*info
= valloc_hash
? g_hash_table_lookup (valloc_hash
, addr
) : NULL
;
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
;
170 g_hash_table_remove (valloc_hash
, info
);
172 BEGIN_CRITICAL_SECTION
;
173 res
= munmap (addr
, length
);
174 END_CRITICAL_SECTION
;
177 mono_account_mem (type
, -(ssize_t
)length
);
183 mono_file_map (size_t length
, int flags
, int fd
, guint64 offset
, void **ret_handle
)
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
)
195 if (flags
& MONO_MMAP_32BIT
)
199 /* emscripten throws an exception on 0 length */
202 BEGIN_CRITICAL_SECTION
;
203 ptr
= mmap (0, length
, prot
, mflags
, fd
, offset
);
204 END_CRITICAL_SECTION
;
205 if (ptr
== MAP_FAILED
)
207 *ret_handle
= (void*)length
;
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
)
223 BEGIN_CRITICAL_SECTION
;
224 res
= munmap (addr
, (size_t)handle
);
225 END_CRITICAL_SECTION
;
231 mono_mprotect (void *addr
, size_t length
, int flags
)
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
;
246 mono_shared_area_remove (void)
248 if (malloced_shared_area
)
249 g_free (malloced_shared_area
);
250 malloced_shared_area
= NULL
;
254 mono_shared_area_for_pid (void *pid
)
260 mono_shared_area_unload (void *area
)
265 mono_shared_area_instances (void **array
, int count
)