From: Chris Hanson Date: Sat, 18 Apr 1998 05:39:44 +0000 (+0000) Subject: Add mechanism to reserve the largest available block of memory below X-Git-Tag: 20090517-FFI~4809 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=ed966a381ef5f858838860701de0dbe09de8d7bb;p=mit-scheme.git Add mechanism to reserve the largest available block of memory below 0x04000000 at the earliest possible moment. This maximizes the amount of memory available for Scheme's heap. Unfortunately, it still isn't very much space compared to other platforms, and under Visual C++ it isn't even as much as that provided by Watcom C/C++. I don't know why this is so poor, or whether there is anything to be done about it. --- diff --git a/v7/src/microcode/memmag.h b/v7/src/microcode/memmag.h index 830cc9445..aa6a2762f 100644 --- a/v7/src/microcode/memmag.h +++ b/v7/src/microcode/memmag.h @@ -1,8 +1,8 @@ /* -*-C-*- -$Id: memmag.h,v 1.5 1996/10/02 18:58:05 cph Exp $ +$Id: memmag.h,v 1.6 1998/04/18 05:39:44 cph Exp $ -Copyright (c) 1993-96 Massachusetts Institute of Technology +Copyright (c) 1993-98 Massachusetts Institute of Technology This material was developed by the Scheme project at the Massachusetts Institute of Technology, Department of Electrical Engineering and @@ -47,11 +47,13 @@ extern void winnt_deallocate_registers (void); #include "ntscmlib.h" extern BOOL win32_under_win32s_p (void); +extern char * NT_allocate_heap (unsigned long, unsigned long *); +extern void NT_release_heap (char *, unsigned long); #ifdef WINNT_RAW_ADDRESSES -#define WIN32_ALLOCATE_HEAP win32_system_utilities.allocate_heap -#define WIN32_RELEASE_HEAP win32_system_utilities.release_heap +#define WIN32_ALLOCATE_HEAP NT_allocate_heap +#define WIN32_RELEASE_HEAP NT_release_heap #else /* not WINNT_RAW_ADDRESSES */ @@ -86,7 +88,7 @@ WIN32_ALLOCATE_HEAP (unsigned long size, unsigned long * handle) total_fudge = (actual_fudge_1 + actual_fudge_2); actual_size = (size + total_fudge); - base = (win32_system_utilities.allocate_heap (actual_size, handle)); + base = (NT_allocate_heap (actual_size, handle)); if (base == ((char *) NULL)) return (base); @@ -112,8 +114,7 @@ WIN32_RELEASE_HEAP (char * area, unsigned long handle) (Scheme_Code_Segment_Selector, Scheme_Data_Segment_Selector, Scheme_Stack_Segment_Selector); - win32_system_utilities.release_heap ((area - total_fudge), handle); - return; + NT_release_heap ((area - total_fudge), handle); } #endif /* WINNT_RAW_ADDRESSES */ diff --git a/v7/src/microcode/ntgui.c b/v7/src/microcode/ntgui.c index d1bcba4ff..cd88e5fe9 100644 --- a/v7/src/microcode/ntgui.c +++ b/v7/src/microcode/ntgui.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: ntgui.c,v 1.22 1998/04/16 06:05:39 cph Exp $ +$Id: ntgui.c,v 1.23 1998/04/18 05:39:22 cph Exp $ Copyright (c) 1993-98 Massachusetts Institute of Technology @@ -44,6 +44,7 @@ MIT in each case. */ extern /*static*/ HANDLE ghInstance = 0; extern void scheme_main (int argc, const char ** argv); +extern void NT_preallocate_heap (void); BOOL InitApplication(HANDLE); BOOL InitInstance(HANDLE, int); @@ -58,8 +59,8 @@ WinMain (HANDLE hInst, HANDLE hPrevInst, LPSTR lpCmdLine, int nCmdShow) char **argv; extern int main (int, char **); + NT_preallocate_heap (); ghInstance = hInst; - { int cmdlen = strlen(lpCmdLine); int maxargs = cmdlen/2+2; diff --git a/v7/src/microcode/nttop.c b/v7/src/microcode/nttop.c index 274820429..75ed5496a 100644 --- a/v7/src/microcode/nttop.c +++ b/v7/src/microcode/nttop.c @@ -1,8 +1,8 @@ /* -*-C-*- -$Id: nttop.c,v 1.24 1997/10/26 08:04:18 cph Exp $ +$Id: nttop.c,v 1.25 1998/04/18 05:39:09 cph Exp $ -Copyright (c) 1993-97 Massachusetts Institute of Technology +Copyright (c) 1993-98 Massachusetts Institute of Technology This material was developed by the Scheme project at the Massachusetts Institute of Technology, Department of Electrical Engineering and @@ -207,6 +207,95 @@ OS_quit (int code, int abnormal_p) return; } +/* Memory Allocation */ + +static LPVOID NT_heap_base; +static DWORD NT_heap_size; +static DWORD NT_heap_error; +#define SCHEME_ADDR_LIMIT 0x04000000 + +void +NT_preallocate_heap (void) +{ + MEMORY_BASIC_INFORMATION largest; + DWORD scan = 0; + (largest.RegionSize) = 0; + while (scan < SCHEME_ADDR_LIMIT) + { + MEMORY_BASIC_INFORMATION info; + (void) VirtualQuery (((LPCVOID) scan), (&info), (sizeof (info))); + if ((info.State) == MEM_FREE) + { + DWORD end = (scan + (info.RegionSize)); + if (end > SCHEME_ADDR_LIMIT) + (info.RegionSize) -= (end - SCHEME_ADDR_LIMIT); + if ((info.RegionSize) > (largest.RegionSize)) + largest = info; + } + scan += (info.RegionSize); + } + NT_heap_size = (largest.RegionSize); + NT_heap_base + = (VirtualAlloc ((largest.BaseAddress), + NT_heap_size, + MEM_RESERVE, + PAGE_READWRITE)); + if (NT_heap_base == 0) + NT_heap_error = (GetLastError ()); +} + +char * +NT_allocate_heap (unsigned long size, unsigned long * handle) +{ + if (NT_heap_base == 0) + { + SYSTEM_INFO info; + LPVOID start = 0; + LPVOID base; + GetSystemInfo (&info); + while (1) + { + start = (((char *) start) + (info . dwPageSize)); + base + = (VirtualAlloc (start, + size, + (MEM_RESERVE | MEM_COMMIT), + PAGE_READWRITE)); + if (base != 0) + break; + } + (* handle) = size; + return ((char *) base); + } + else + { + DWORD size2 = ((size <= NT_heap_size) ? size : NT_heap_size); + LPVOID base + = (VirtualAlloc (NT_heap_base, + size2, + MEM_COMMIT, + PAGE_READWRITE)); + (* handle) = size2; + return ((char *) base); + } +} + +void +NT_release_heap (char * area, unsigned long handle) +{ + VirtualFree (((LPVOID) area), + ((DWORD) handle), + ((DWORD) MEM_DECOMMIT)); + if (NT_heap_base == 0) + VirtualFree (((LPVOID) area), + ((DWORD) 0), + ((DWORD) MEM_RELEASE)); + else + VirtualFree (NT_heap_base, + ((DWORD) 0), + ((DWORD) MEM_RELEASE)); +} + #ifndef EAGAIN #define EAGAIN ERRNO_NONBLOCK #endif