Add mechanism to reserve the largest available block of memory below
authorChris Hanson <org/chris-hanson/cph>
Sat, 18 Apr 1998 05:39:44 +0000 (05:39 +0000)
committerChris Hanson <org/chris-hanson/cph>
Sat, 18 Apr 1998 05:39:44 +0000 (05:39 +0000)
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.

v7/src/microcode/memmag.h
v7/src/microcode/ntgui.c
v7/src/microcode/nttop.c

index 830cc94451281b98997cd46dfe0afadc27e1b141..aa6a2762f126b077c3b5e9d6607f8e9bf0164893 100644 (file)
@@ -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 */
index d1bcba4ffbccd24ce720b5f442a057cf85bc6706..cd88e5fe909a2ddc91aca4c39818908466cf1b6b 100644 (file)
@@ -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. */
 \f
 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;
index 27482042996d8b1cf5e77c408e7407811dcdd167..75ed5496aa91b39c4c6ec26a65ecb2584f28dfee 100644 (file)
@@ -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;
 }
 \f
+/* 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));
+}
+\f
 #ifndef EAGAIN
 #define EAGAIN ERRNO_NONBLOCK
 #endif