Commit 55d615e0 authored by sof's avatar sof
Browse files

[project @ 1999-01-18 09:20:08 by sof]

'Native' Wni32 implementation of getMBlock(). Also added a Win32 impl.
of freeMBlock() in case that ever should become useful.
parent 0a16b413
/* -----------------------------------------------------------------------------
* $Id: MBlock.c,v 1.4 1999/01/14 18:31:17 sof Exp $
* $Id: MBlock.c,v 1.5 1999/01/18 09:20:08 sof Exp $
*
* MegaBlock Allocator Interface. This file contains all the dirty
* architecture-dependent hackery required to get a chunk of aligned
......@@ -48,11 +48,6 @@
*/
#define ASK_FOR_MEM_AT 0x50000000
#elif cygwin32_TARGET_OS
/* Any ideas?
*/
#define ASK_FOR_MEM_AT 0x50000000
#elif solaris2_TARGET_OS
/* guess */
#define ASK_FOR_MEM_AT 0x50000000
......@@ -70,6 +65,8 @@ getMBlock(void)
return getMBlocks(1);
}
#ifndef _WIN32
void *
getMBlocks(nat n)
{
......@@ -85,29 +82,8 @@ getMBlocks(nat n)
close(fd);
}
#else
# ifdef _WIN32
{
/* Note: on 95, the legal range for next_request is: [0x00400000, 0x7fffffff]
under NT it is: [0x00010000, 0x7fffffff]
We start allocating at 0x50000000, hopefully that's not conflicting with
others.. (ToDo: have the allocator try to gracefully rebase itself in
case our initial guess is conflicting with others.)
*/
ret = VirtualAlloc(next_request, size, MEM_RESERVE | MEM_COMMIT , PAGE_READWRITE);
if (!ret) {
# ifdef DEBUG
fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %d\n", GetLastError());
# endif
ret =(void*)-1;
}
return ret;
}
# else
ret = mmap(next_request, size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
# endif
#endif
if (ret == (void *)-1) {
......@@ -130,3 +106,113 @@ getMBlocks(nat n)
return ret;
}
#else /* _WIN32 */
/*
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 .)
Reserving memory doesn't allocate physical storage (not even in the
page file), this is done by committing pages (or mega-blocks in
our case).
*/
void *
getMBlocks(nat n)
{
static char* base_non_committed = (char*)0;
static char* base_mblocks = (char*)0;
static char* next_request = (char*)0;
void* ret = (void*)0;
lnat size = MBLOCK_SIZE * n;
/* Reserve VM 128M at the time to try to minimise the slop cost. */
#define SIZE_RESERVED_POOL ( 128 * 1024 * 1024 )
if ( (base_non_committed == 0) ||
(next_request + size > base_non_committed + SIZE_RESERVED_POOL) ) {
base_non_committed = VirtualAlloc ( NULL
, SIZE_RESERVED_POOL
, MEM_RESERVE
, PAGE_READWRITE
);
if ( base_non_committed == 0 ) {
# ifdef DEBUG
fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %d\n", GetLastError());
# endif
ret=(void*)-1;
} else {
/* The returned pointer is not aligned on a mega-block boundary. Make it. */
base_mblocks = (char*)((unsigned)base_non_committed & (unsigned)0xfff00000) + 0x100000;
# if 0
fprintf(stderr, "Dropping %d bytes off of 128M chunk\n",
(unsigned)base_mblocks - (unsigned)base_non_committed);
# endif
if ( ((char*)base_mblocks + size) > ((char*)base_non_committed + SIZE_RESERVED_POOL) ) {
# ifdef DEBUG
fprintf(stderr, "oops, committed too small a region to start with.");
# endif
ret=(void*)-1;
} else {
next_request = base_mblocks;
}
}
}
/* Commit the mega block(s) to phys mem */
if ( ret != (void*)-1 ) {
ret = VirtualAlloc(next_request, size, MEM_COMMIT, PAGE_READWRITE);
if (ret == NULL) {
# ifdef DEBUG
fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %d\n", GetLastError());
# endif
ret=(void*)-1;
}
}
if (((W_)ret & MBLOCK_MASK) != 0) {
barf("GetMBlock: misaligned block returned");
}
IF_DEBUG(gc,fprintf(stderr,"Allocated %d megablock(s) at %x\n",n,(nat)ret));
next_request = (char*)next_request + size;
mblocks_allocated += n;
return ret;
}
/* 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.
Currently unused.
*/
#if 0
void
freeMBlock(void* p, nat n)
{
BOOL rc;
rc = VirtualFree(p, n * MBLOCK_SIZE , MEM_DECOMMIT );
if (rc == FALSE) {
# ifdef DEBUG
fprintf(stderr, "freeMBlocks: VirtualFree failed with: %d\n", GetLastError());
# endif
}
}
#endif
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment