Merge pull request #4630 from BrzVlad/feature-valloc-limit
[mono.git] / mono / utils / mono-mmap.c
index 91fe5a12def4517d7c1d364df7117cef53aa988f..4bd214d4dddc26787ab4c8c702c5cf667f74a08e 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * mono-mmap.c: Support for mapping code into the process address space
+/**
+ * \file
+ * Support for mapping code into the process address space
  *
  * Author:
  *   Mono Team (mono-list@lists.ximian.com)
@@ -80,16 +81,29 @@ aligned_address (char *mem, size_t size, size_t alignment)
        return aligned;
 }
 
-static volatile size_t allocation_count [MONO_MEM_ACCOUNT_MAX];
+static size_t allocation_count [MONO_MEM_ACCOUNT_MAX];
+static size_t total_allocation_count;
+static size_t alloc_limit;
 
 void
 account_mem (MonoMemAccountType type, ssize_t size)
 {
-#if SIZEOF_VOID_P == 4
-       InterlockedAdd ((volatile gint32*)&allocation_count [type], (gint32)size);
-#else
-       InterlockedAdd64 ((volatile gint64*)&allocation_count [type], (gint64)size);
-#endif
+       InterlockedAddP (&allocation_count [type], size);
+       InterlockedAddP (&total_allocation_count, size);
+}
+
+void
+mono_valloc_set_limit (size_t size)
+{
+       alloc_limit = size;
+}
+
+gboolean
+mono_valloc_can_alloc (size_t size)
+{
+       if (alloc_limit)
+               return (total_allocation_count + size) < alloc_limit;
+       return TRUE;
 }
 
 const char*
@@ -155,6 +169,12 @@ mono_pagesize (void)
        return saved_pagesize;
 }
 
+int
+mono_valloc_granule (void)
+{
+       return mono_pagesize ();
+}
+
 static int
 prot_from_flags (int flags)
 {
@@ -171,17 +191,15 @@ prot_from_flags (int flags)
 
 /**
  * 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
+ * \param addr memory address
+ * \param length memory area size
+ * \param flags protection flags
+ * Allocates \p length bytes of virtual memory with the \p flags
+ * protection. \p addr can be a preferred memory address or a
+ * mandatory one if MONO_MMAP_FIXED is set in \p flags.
+ * \p addr must be pagesize aligned and can be NULL.
+ * \p 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, MonoMemAccountType type)
@@ -189,6 +207,10 @@ mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
        void *ptr;
        int mflags = 0;
        int prot = prot_from_flags (flags);
+
+       if (!mono_valloc_can_alloc (length))
+               return NULL;
+
        /* translate the flags */
        if (flags & MONO_MMAP_FIXED)
                mflags |= MAP_FIXED;
@@ -219,12 +241,10 @@ mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
 
 /**
  * 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.
+ * \param addr memory address returned by mono_valloc ()
+ * \param length size of memory area
+ * Remove the memory mapping at the address \p addr.
+ * \returns \c 0 on success.
  */
 int
 mono_vfree (void *addr, size_t length, MonoMemAccountType type)
@@ -241,19 +261,17 @@ mono_vfree (void *addr, size_t length, MonoMemAccountType type)
 
 /**
  * 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 ().
- *
+ * \param length size of data to map
+ * \param flags protection flags
+ * \param fd file descriptor
+ * \param offset offset in the file
+ * \param ret_handle pointer to storage for returning a handle for the map
+ * Map the area of the file pointed to by the file descriptor \p fd, at offset
+ * \p offset and of size \p length in memory according to the protection flags
+ * \p flags.
+ * \p offset and \p length must be multiples of the page size.
+ * \p ret_handle must point to a void*: this value must be used when unmapping
+ * the memory area using \c mono_file_unmap().
  */
 void*
 mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
@@ -282,13 +300,11 @@ mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_hand
 
 /**
  * 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.
+ * \param addr memory address returned by mono_file_map ()
+ * \param handle handle of memory map
+ * Remove the memory mapping at the address \p addr.
+ * \p handle must be the value returned in ret_handle by \c mono_file_map().
+ * \returns \c 0 on success.
  */
 int
 mono_file_unmap (void *addr, void *handle)
@@ -304,18 +320,16 @@ mono_file_unmap (void *addr, void *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
+ * \param addr memory address
+ * \param length size of memory area
+ * \param flags new protection flags
+ * Change the protection for the memory area at \p addr for \p length bytes
+ * to matche the supplied \p flags.
+ * If \p 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.
+ * \p addr must be aligned to the page size.
+ * \p length must be a multiple of the page size.
+ * \returns \c 0 on success.
  */
 #if defined(__native_client__)
 int
@@ -364,6 +378,12 @@ mono_pagesize (void)
        return 4096;
 }
 
+int
+mono_valloc_granule (void)
+{
+       return mono_pagesize ();
+}
+
 void*
 mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
 {
@@ -404,7 +424,7 @@ static gboolean
 shared_area_disabled (void)
 {
        if (!use_shared_area) {
-               if (g_getenv ("MONO_DISABLE_SHARED_AREA"))
+               if (g_hasenv ("MONO_DISABLE_SHARED_AREA"))
                        use_shared_area = -1;
                else
                        use_shared_area = 1;