#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-#ifndef mingw32_TARGET_OS
+#ifndef mingw32_HOST_OS
# ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
# endif
#if HAVE_WINDOWS_H
#include <windows.h>
#endif
-#if darwin_TARGET_OS
+#if darwin_HOST_OS
#include <mach/vm_map.h>
#endif
chunk, on the grounds that this is aligned and likely to be free.
If it turns out that we were wrong, we have to munmap() and try
again using the general method.
+
+ Note on posix_memalign(): this interface is available on recent
+ systems and appears to provide exactly what we want. However, it
+ turns out not to be as good as our mmap() implementation, because
+ it wastes extra space (using double the address space, in a test on
+ x86_64/Linux). The problem seems to be that posix_memalign()
+ returns memory that can be free()'d, so the library must store
+ extra information along with the allocated block, thus messing up
+ the alignment. Hence, we don't use posix_memalign() for now.
+
-------------------------------------------------------------------------- */
-#if !defined(mingw32_TARGET_OS) && !defined(cygwin32_TARGET_OS)
+#if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS)
// A wrapper around mmap(), to abstract away from OS differences in
// the mmap() interface.
{
void *ret;
-#if defined(solaris2_TARGET_OS) || defined(irix_TARGET_OS)
+#if defined(solaris2_HOST_OS) || defined(irix_HOST_OS)
{
int fd = open("/dev/zero",O_RDONLY);
ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
close(fd);
}
-#elif hpux_TARGET_OS
+#elif hpux_HOST_OS
ret = mmap(addr, size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
-#elif darwin_TARGET_OS
+#elif darwin_HOST_OS
// Without MAP_FIXED, Apple's mmap ignores addr.
// With MAP_FIXED, it overwrites already mapped regions, whic
// mmap(0, ... MAP_FIXED ...) is worst of all: It unmaps the program text
if(!addr || err) // try to allocate anywhere
err = vm_allocate(mach_task_self(),(vm_address_t*) &ret, size, TRUE);
- if(err) // don't know what the error codes mean exactly
- barf("memory allocation failed (requested %lu bytes)", size);
- else
+ if(err) {
+ // don't know what the error codes mean exactly, assume it's
+ // not our problem though.
+ errorBelch("memory allocation failed (requested %lu bytes)", size);
+ stg_exit(EXIT_FAILURE);
+ } else {
vm_protect(mach_task_self(),ret,size,FALSE,VM_PROT_READ|VM_PROT_WRITE);
+ }
#else
ret = mmap(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE, -1, 0);
return ret;
}
-#else /* defined(mingw32_TARGET_OS) || defined(cygwin32_TARGET_OS) */
+void
+freeAllMBlocks(void)
+{
+ /* XXX Do something here */
+}
+
+#else /* defined(mingw32_HOST_OS) || defined(cygwin32_HOST_OS) */
/*
On Win32 platforms we make use of the two-phased virtual memory API
our case).
*/
-char* base_non_committed = (char*)0;
-char* end_non_committed = (char*)0;
+static char* base_non_committed = (char*)0;
+static char* end_non_committed = (char*)0;
+
+static void *membase;
/* Default is to reserve 256M of VM to minimise the slop cost. */
#define SIZE_RESERVED_POOL ( 256 * 1024 * 1024 )
, MEM_RESERVE
, PAGE_READWRITE
);
+ membase = base_non_committed;
if ( base_non_committed == 0 ) {
- errorBelch("getMBlocks: VirtualAlloc failed with: %ld\n", GetLastError());
- ret=(void*)-1;
+ errorBelch("getMBlocks: VirtualAlloc MEM_RESERVE %lu failed with: %ld\n", size_reserved_pool, GetLastError());
+ ret=(void*)-1;
} else {
end_non_committed = (char*)base_non_committed + (unsigned long)size_reserved_pool;
/* The returned pointer is not aligned on a mega-block boundary. Make it. */
if ( ret != (void*)-1 ) {
ret = VirtualAlloc(next_request, size, MEM_COMMIT, PAGE_READWRITE);
if (ret == NULL) {
- debugBelch("getMBlocks: VirtualAlloc failed with: %ld\n", GetLastError());
+ debugBelch("getMBlocks: VirtualAlloc MEM_COMMIT %lu failed with: %ld\n", size, GetLastError());
ret=(void*)-1;
}
}
return ret;
}
+void
+freeAllMBlocks(void)
+{
+ BOOL rc;
+
+ rc = VirtualFree(membase, 0, MEM_RELEASE);
+
+ if (rc == FALSE) {
+ debugBelch("freeAllMBlocks: VirtualFree failed with: %ld\n", GetLastError());
+ }
+}
+
/* Hand back the physical memory that is allocated to a mega-block.
ToDo: chain the released mega block onto some list so that
getMBlocks() can get at it.