X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FMBlock.c;h=eaf680146a895a358b645cfff99e4bdd65145e1e;hb=a1c9a60f9d3b45184f723b454017edcbf258f70e;hp=109b23e549503aecfae27d8ed13dd01c54163903;hpb=b158e0c40714496f478a9801a5c56ca894c1af25;p=ghc-hetmet.git diff --git a/ghc/rts/MBlock.c b/ghc/rts/MBlock.c index 109b23e..eaf6801 100644 --- a/ghc/rts/MBlock.c +++ b/ghc/rts/MBlock.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: MBlock.c,v 1.21 2001/01/16 11:54:25 simonmar Exp $ + * $Id: MBlock.c,v 1.29 2002/07/17 09:21:50 simonmar Exp $ * * (c) The GHC Team 1998-1999 * @@ -9,7 +9,8 @@ * * ---------------------------------------------------------------------------*/ -#define NON_POSIX_SOURCE +/* This is non-posix compliant. */ +/* #include "PosixSource.h" */ #include "Rts.h" #include "RtsUtils.h" @@ -39,6 +40,8 @@ #include #endif +#include + lnat mblocks_allocated = 0; void * @@ -47,7 +50,7 @@ getMBlock(void) return getMBlocks(1); } -#ifndef _WIN32 +#if !defined(mingw32_TARGET_OS) && !defined(cygwin32_TARGET_OS) void * getMBlocks(nat n) { @@ -65,7 +68,7 @@ getMBlocks(nat n) #elif hpux_TARGET_OS ret = mmap(next_request, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); -#elif macosx_TARGET_OS +#elif darwin_TARGET_OS ret = mmap(next_request, size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); #else @@ -75,7 +78,7 @@ getMBlocks(nat n) if (ret == (void *)-1) { if (errno == ENOMEM) { - barf("getMBlock: out of memory"); + barf("getMBlock: out of memory (blocks requested: %d)", n); } else { barf("GetMBlock: mmap failed"); } @@ -85,7 +88,7 @@ getMBlocks(nat n) barf("GetMBlock: misaligned block %p returned when allocating %d megablock(s) at %p", ret, n, next_request); } - IF_DEBUG(gc,fprintf(stderr,"Allocated %d megablock(s) at %x\n",n,(nat)ret)); + IF_DEBUG(gc,fprintf(stderr,"Allocated %d megablock(s) at %p\n",n,ret)); next_request += size; @@ -94,28 +97,31 @@ getMBlocks(nat n) return ret; } -#else /* _WIN32 */ +#else /* defined(mingw32_TARGET_OS) || defined(cygwin32_TARGET_OS) */ /* On Win32 platforms we make use of the two-phased virtual memory API to allocate mega blocks. We proceed as follows: - Reserve a large chunk of VM (128M at the time), but don't supply a - base address that's aligned on a MB boundary. Instead we round up to the - nearest from the chunk of VM we're given back from the OS (at the - moment we just leave the 'slop' at the beginning of the reserved - chunk unused - ToDo: reuse it .) + Reserve a large chunk of VM (256M at the time, or what the user asked + for via the -M option), but don't supply a base address that's aligned on + a MB boundary. Instead we round up to the nearest mblock from the chunk of + VM we're handed back from the OS (at the moment we just leave the 'slop' at + the beginning of the reserved chunk unused - ToDo: reuse it .) Reserving memory doesn't allocate physical storage (not even in the - page file), this is done by committing pages (or mega-blocks in + page file), this is done later on by committing pages (or mega-blocks in our case). - */ char* base_non_committed = (char*)0; +char* end_non_committed = (char*)0; -/* Reserve VM 128M at the time to try to minimise the slop cost. */ -#define SIZE_RESERVED_POOL ( 128 * 1024 * 1024 ) +/* Default is to reserve 256M of VM to minimise the slop cost. */ +#define SIZE_RESERVED_POOL ( 256 * 1024 * 1024 ) + +/* Number of bytes reserved */ +static unsigned long size_reserved_pool = SIZE_RESERVED_POOL; /* This predicate should be inlined, really. */ /* TODO: this only works for a single chunk */ @@ -123,7 +129,7 @@ int is_heap_alloced(const void* x) { return (((char*)(x) >= base_non_committed) && - ((char*)(x) <= (base_non_committed + SIZE_RESERVED_POOL))); + ((char*)(x) <= end_non_committed)); } void * @@ -134,35 +140,36 @@ getMBlocks(nat n) void* ret = (void*)0; lnat size = MBLOCK_SIZE * n; - - if ( (base_non_committed == 0) || - (next_request + size > base_non_committed + SIZE_RESERVED_POOL) ) { -#ifdef ENABLE_WIN32_DLL_SUPPORT - if (base_non_committed) - barf("Windows programs can only use 128Mb of heap; sorry!"); -#endif + + if ( (base_non_committed == 0) || (next_request + size > end_non_committed) ) { + if (base_non_committed) { + barf("RTS exhausted max heap size (%d bytes)\n", size_reserved_pool); + } + if (RtsFlags.GcFlags.maxHeapSize != 0) { + size_reserved_pool = BLOCK_SIZE * RtsFlags.GcFlags.maxHeapSize; + if (size_reserved_pool < MBLOCK_SIZE) { + size_reserved_pool = 2*MBLOCK_SIZE; + } + } base_non_committed = VirtualAlloc ( NULL - , SIZE_RESERVED_POOL + , size_reserved_pool , MEM_RESERVE , PAGE_READWRITE ); if ( base_non_committed == 0 ) { -# if 1 /*def DEBUG*/ - fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %d\n", GetLastError()); -# endif + fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %ld\n", GetLastError()); ret=(void*)-1; } else { - /* The returned pointer is not aligned on a mega-block boundary. Make it. */ - base_mblocks = (char*)((unsigned long)base_non_committed & (unsigned long)0xfff00000) + MBLOCK_SIZE; -# if 0 - fprintf(stderr, "Dropping %d bytes off of 128M chunk\n", + 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. */ + base_mblocks = (char*)((unsigned long)base_non_committed & (unsigned long)0xfff00000) + MBLOCK_SIZE; +# if 0 + fprintf(stderr, "getMBlocks: Dropping %d bytes off of 256M chunk\n", (unsigned)base_mblocks - (unsigned)base_non_committed); -# endif +# endif - if ( ((char*)base_mblocks + size) > ((char*)base_non_committed + SIZE_RESERVED_POOL) ) { -# if 1 /*def DEBUG*/ - fprintf(stderr, "oops, committed too small a region to start with."); -# endif + if ( ((char*)base_mblocks + size) > end_non_committed ) { + fprintf(stderr, "getMBlocks: oops, committed too small a region to start with."); ret=(void*)-1; } else { next_request = base_mblocks; @@ -173,19 +180,20 @@ getMBlocks(nat n) if ( ret != (void*)-1 ) { ret = VirtualAlloc(next_request, size, MEM_COMMIT, PAGE_READWRITE); if (ret == NULL) { -# if 1 /*def DEBUG*/ - fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %d\n", GetLastError()); -# endif + fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %ld\n", GetLastError()); ret=(void*)-1; } } if (((W_)ret & MBLOCK_MASK) != 0) { - barf("GetMBlock: misaligned block returned"); + barf("getMBlocks: misaligned block returned"); } - IF_DEBUG(gc,fprintf(stderr,"Allocated %d megablock(s) at %x\n",n,(nat)ret)); + if (ret == (void*)-1) { + barf("getMBlocks: unknown memory allocation failure on Win32."); + } + IF_DEBUG(gc,fprintf(stderr,"Allocated %d megablock(s) at 0x%x\n",n,(nat)ret)); next_request = (char*)next_request + size; mblocks_allocated += n; @@ -208,9 +216,9 @@ freeMBlock(void* p, nat n) rc = VirtualFree(p, n * MBLOCK_SIZE , MEM_DECOMMIT ); if (rc == FALSE) { -# ifdef DEBUG +# ifdef DEBUG fprintf(stderr, "freeMBlocks: VirtualFree failed with: %d\n", GetLastError()); -# endif +# endif } }