+/*
+ * mono-mmap.c: Support for mapping code into the process address space
+ *
+ * Author:
+ * Mono Team (mono-list@lists.ximian.com)
+ *
+ * Copyright 2001-2008 Novell, Inc.
+ */
+
#include "config.h"
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
#include <windows.h>
#include <io.h>
#else
return sarea;
}
-#ifdef PLATFORM_WIN32
+static char*
+aligned_address (char *mem, size_t size, size_t alignment)
+{
+ char *aligned = (char*)((gulong)(mem + (alignment - 1)) & ~(alignment - 1));
+ g_assert (aligned >= mem && aligned + size <= mem + size + alignment && !((gulong)aligned & (alignment - 1)));
+ return aligned;
+}
+
+#ifdef HOST_WIN32
int
mono_pagesize (void)
return ptr;
}
+void*
+mono_valloc_aligned (size_t length, size_t alignment, int flags)
+{
+ int prot = prot_from_flags (flags);
+ char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot);
+ char *aligned;
+
+ if (!mem)
+ return NULL;
+
+ aligned = aligned_address (mem, length, alignment);
+
+ aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot);
+ g_assert (aligned);
+
+ return aligned;
+}
+
+#define HAVE_VALLOC_ALIGNED
+
int
mono_vfree (void *addr, size_t length)
{
- int res = VirtualFree (addr, 0, MEM_RELEASE);
+ MEMORY_BASIC_INFORMATION mbi;
+ SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi));
+ BOOL res;
+
+ g_assert (query_result);
+
+ res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE);
g_assert (res);
return 0;
}
-#elif defined(HAVE_MMAP)
+#else
+#if defined(HAVE_MMAP)
/**
* mono_pagesize:
memset (addr, 0, length);
#else
memset (addr, 0, length);
+#ifdef HAVE_MADVISE
madvise (addr, length, MADV_DONTNEED);
madvise (addr, length, MADV_FREE);
+#else
+ posix_madvise (addr, length, POSIX_MADV_DONTNEED);
+#endif
#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);
+}
+
+void*
+mono_valloc_aligned (size_t length, size_t alignment, int flags)
+{
+ g_assert_not_reached ();
+}
+
+#define HAVE_VALLOC_ALIGNED
+
+int
+mono_vfree (void *addr, size_t length)
+{
+ 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 // HAVE_MMAP
+
+#if defined(HAVE_SHM_OPEN) && !defined (DISABLE_SHARED_PERFCOUNTERS)
+
static int
mono_shared_area_instances_slow (void **array, int count, gboolean cleanup)
{
return j;
}
+#if (defined (__MACH__) && defined (TARGET_ARM))
static int
mono_shared_area_instances_helper (void **array, int count, gboolean cleanup)
{
else
break;
}
- if (curpid != pid && kill (pid, SIGCONT) == -1 && errno == ESRCH) {
+ if (curpid != pid && kill (pid, 0) == -1 && (errno == ESRCH || errno == ENOMEM)) {
char buf [128];
g_snprintf (buf, sizeof (buf), "/mono.%d", pid);
shm_unlink (buf);
g_dir_close (dir);
return i;
}
+#else
+#define mono_shared_area_instances_helper mono_shared_area_instances_slow
+#endif
void*
mono_shared_area (void)
{
return mono_shared_area_instances_helper (array, count, FALSE);
}
-
#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, guint64 offset, void **ret_handle)
-{
- guint64 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;
-}
-
void*
mono_shared_area (void)
{
return 0;
}
-#endif
+#endif // HAVE_SHM_OPEN
+
+#endif // HOST_WIN32
+#ifndef HAVE_VALLOC_ALIGNED
+void*
+mono_valloc_aligned (size_t size, size_t alignment, int flags)
+{
+ /* Allocate twice the memory to be able to put the block on an aligned address */
+ char *mem = mono_valloc (NULL, size + alignment, flags);
+ char *aligned;
+
+ if (!mem)
+ return NULL;
+
+ aligned = aligned_address (mem, size, alignment);
+
+ if (aligned > mem)
+ mono_vfree (mem, aligned - mem);
+ if (aligned + size < mem + size + alignment)
+ mono_vfree (aligned + size, (mem + size + alignment) - (aligned + size));
+
+ return aligned;
+}
+#endif