]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygheap.h (struct user_heap_info): Add slop member.
authorCorinna Vinschen <corinna@vinschen.de>
Tue, 31 Oct 2006 18:41:16 +0000 (18:41 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Tue, 31 Oct 2006 18:41:16 +0000 (18:41 +0000)
* heap.cc (heap_init): Add slop factor to heap allocation.  Add
comment.
* mmap.cc (MapViewNT): Allocate memory maps top down.
(fhandler_dev_zero::mmap): Ditto.
* shared.cc (shared_info::heap_slop_size): New method.
(shared_info::heap_chunk_size): Don't use debug_printf at early stage.
* shared_info.h (SHARED_INFO_CB): Accomodate change to shared_info.
(CURR_SHARED_MAGIC): Ditto.
(class shared_info): Add heap_slop member.  Declare heap_slop_size.
* wincap.h: Define heapslop throughout.
* wincap.cc: Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.h
winsup/cygwin/heap.cc
winsup/cygwin/mmap.cc
winsup/cygwin/shared.cc
winsup/cygwin/shared_info.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index fddfd6bf73107f4a54ec05da48b14b72308aa3f3..212bbabdb35526a3f670d05b3516a35330758c9d 100644 (file)
@@ -1,3 +1,18 @@
+2006-10-31  Corinna Vinschen  <corinna@vinschen.de>
+
+       * cygheap.h (struct user_heap_info): Add slop member.
+       * heap.cc (heap_init): Add slop factor to heap allocation.  Add
+       comment.
+       * mmap.cc (MapViewNT): Allocate memory maps top down.
+       (fhandler_dev_zero::mmap): Ditto.
+       * shared.cc (shared_info::heap_slop_size): New method.
+       (shared_info::heap_chunk_size): Don't use debug_printf at early stage.
+       * shared_info.h (SHARED_INFO_CB): Accomodate change to shared_info.
+       (CURR_SHARED_MAGIC): Ditto.
+       (class shared_info): Add heap_slop member.  Declare heap_slop_size.
+       * wincap.h: Define heapslop throughout.
+       * wincap.cc: Ditto.
+
 2006-10-31  Corinna Vinschen  <corinna@vinschen.de>
 
        * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop
index 35db5cad894cdbee867d5d15cd25acba019ce1d1..85da8f6ed94cb534829c65b9db7d9d31c8d969e9 100644 (file)
@@ -262,6 +262,7 @@ struct user_heap_info
   void *top;
   void *max;
   unsigned chunk;
+  unsigned slop;
 };
 
 struct hook_chain
index 63fc93520a2f239a0748b0662917160e25573f3e..5278febfc35d7695dbd7fd3d84315aa565bbce37 100644 (file)
@@ -41,21 +41,38 @@ heap_init ()
   if (!cygheap->user_heap.base)
     {
       cygheap->user_heap.chunk = cygwin_shared->heap_chunk_size ();
+      /* For some obscure reason Vista and 2003 sometimes reserve space after
+        calls to CreateProcess overlapping the spot where the heap has been
+        allocated.  This apparently spoils fork.  The behaviour looks quite
+        arbitrary.  Experiments on Vista show a memory size of 0x37e000 or
+        0x1fd000 overlapping the usual heap by at most 0x1ed000.  So what
+        we do here is to allocate the heap with an extra slop of (by default)
+        0x200000 and set the appropriate pointers to the start of the heap
+        area + slop.  A forking child then creates its heap at the new start
+        address and without the slop factor.  Since this is not entirely
+        foolproof we add a registry setting "heap_slop_in_mb" so the slop
+        factor can be influenced by the user if the need arises. */
+      cygheap->user_heap.slop = cygwin_shared->heap_slop_size ();
       while (cygheap->user_heap.chunk >= MINHEAP_SIZE)
        {
          /* Initialize page mask and default heap size.  Preallocate a heap
           * to assure contiguous memory.  */
-         cygheap->user_heap.ptr = cygheap->user_heap.top =
          cygheap->user_heap.base =
-           VirtualAlloc (NULL, cygheap->user_heap.chunk, alloctype, PAGE_NOACCESS);
+           VirtualAlloc (NULL, cygheap->user_heap.chunk
+                               + cygheap->user_heap.slop,
+                         alloctype, PAGE_NOACCESS);
          if (cygheap->user_heap.base)
            break;
          cygheap->user_heap.chunk -= 1 * 1024 * 1024;
        }
       if (cygheap->user_heap.base == NULL)
-       api_fatal ("unable to allocate heap, heap_chunk_size %d, %E",
-                  cygheap->user_heap.chunk);
-      cygheap->user_heap.max = (char *) cygheap->user_heap.base + cygheap->user_heap.chunk;
+       api_fatal ("unable to allocate heap, heap_chunk_size %p, slop %p, %E",
+                  cygheap->user_heap.chunk, cygheap->user_heap.slop);
+      cygheap->user_heap.base = (void *) ((char *) cygheap->user_heap.base
+                                                  + cygheap->user_heap.slop);
+      cygheap->user_heap.ptr = cygheap->user_heap.top = cygheap->user_heap.base;
+      cygheap->user_heap.max = (char *) cygheap->user_heap.base
+                              + cygheap->user_heap.chunk;
     }
   else
     {
index 1c1afba57f9d5db640efbdb54d48897e8738cc39..31bac5869ed124e31105921d810760490051e600 100644 (file)
@@ -350,7 +350,8 @@ MapViewNT (HANDLE h, void *addr, size_t len, DWORD openflags,
   void *base = addr;
   ULONG commitsize = attached (prot) ? 0 : len;
   ULONG viewsize = len;
-  ULONG alloc_type = base && !wincap.is_wow64 () ? AT_ROUND_TO_PAGE : 0;
+  ULONG alloc_type = (base && !wincap.is_wow64 () ? AT_ROUND_TO_PAGE : 0)
+                    | MEM_TOP_DOWN;
 
   /* Try mapping using the given address first, even if it's NULL.
      If it failed, and addr was not NULL and flags is not MAP_FIXED,
@@ -1669,7 +1670,8 @@ fhandler_dev_zero::mmap (caddr_t *addr, size_t len, int prot,
           when using the (non-POSIX, yay-Linux) MAP_NORESERVE flag.
       */
       DWORD protect = gen_protect (prot, flags);
-      DWORD alloc_type = MEM_RESERVE | (noreserve (flags) ? 0 : MEM_COMMIT);
+      DWORD alloc_type = MEM_TOP_DOWN | MEM_RESERVE
+                        | (noreserve (flags) ? 0 : MEM_COMMIT);
       base = VirtualAlloc (*addr, len, alloc_type, protect);
       if (!base && addr && !fixed (flags))
        base = VirtualAlloc (NULL, len, alloc_type, protect);
index 65965b58ba31f951a91f98a52aa66ea81c08d982..4c4b7bc72a3151780c72adbf747083c8fe9e0f9e 100644 (file)
@@ -234,6 +234,33 @@ memory_init ()
   mtinfo_init ();
 }
 
+unsigned
+shared_info::heap_slop_size ()
+{
+  if (!heap_slop)
+    {
+      /* Fetch from registry, first user then local machine.  */
+      for (int i = 0; i < 2; i++)
+       {
+         reg_key reg (i, KEY_READ, NULL);
+
+         if ((heap_slop = reg.get_int ("heap_slop_in_mb", 0)))
+           break;
+         heap_slop = wincap.heapslop ();
+       }
+
+      if (heap_slop < 0)
+       heap_slop = 0;
+      else
+       heap_slop <<= 20;
+#ifdef DEBUGGING
+      system_printf ("fixed heap slop is %p", heap_slop);
+#endif
+    }
+
+  return heap_slop;
+}
+
 unsigned
 shared_info::heap_chunk_size ()
 {
@@ -260,7 +287,9 @@ shared_info::heap_chunk_size ()
        heap_chunk <<= 20;
       if (!heap_chunk)
        heap_chunk = 384 * 1024 * 1024;
-      debug_printf ("fixed heap size is %u", heap_chunk);
+#ifdef DEBUGGING
+      system_printf ("fixed heap size is %u", heap_chunk);
+#endif
     }
 
   return heap_chunk;
index ff93616058cfa693f74d9df2310f1d547311da05..a1a4be0db4708e9f14e143cf9179f93deff46c41 100644 (file)
@@ -143,9 +143,9 @@ public:
                                  cygwin_version.api_minor)
 #define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION)
 
-#define SHARED_INFO_CB 19984
+#define SHARED_INFO_CB 19988
 
-#define CURR_SHARED_MAGIC 0x818f75beU
+#define CURR_SHARED_MAGIC 0xb632a4cU
 
 /* NOTE: Do not make gratuitous changes to the names or organization of the
    below class.  The layout is checksummed to determine compatibility between
@@ -156,11 +156,13 @@ class shared_info
   DWORD cb;
  public:
   unsigned heap_chunk;
+  unsigned heap_slop;
   DWORD sys_mount_table_counter;
 
   tty_list tty;
   void initialize ();
   unsigned heap_chunk_size ();
+  unsigned heap_slop_size ();
 };
 
 extern shared_info *cygwin_shared;
index 9c82e45a7bdc2bad519b1b1bf9375cdfbaf8bdb3..df6765b7ba70e5807f48955d67d8cb271111d94b 100644 (file)
@@ -14,6 +14,7 @@ details. */
 static NO_COPY wincaps wincap_unknown = {
   lock_file_highword:0x0,
   chunksize:0x0,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE,
   is_winnt:false,
   is_server:false,
@@ -72,6 +73,7 @@ static NO_COPY wincaps wincap_unknown = {
 static NO_COPY wincaps wincap_95 = {
   lock_file_highword:0x0,
   chunksize:32 * 1024 * 1024,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE,
   is_winnt:false,
   is_server:false,
@@ -130,6 +132,7 @@ static NO_COPY wincaps wincap_95 = {
 static NO_COPY wincaps wincap_95osr2 = {
   lock_file_highword:0x0,
   chunksize:32 * 1024 * 1024,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE,
   is_winnt:false,
   is_server:false,
@@ -188,6 +191,7 @@ static NO_COPY wincaps wincap_95osr2 = {
 static NO_COPY wincaps wincap_98 = {
   lock_file_highword:0x0,
   chunksize:32 * 1024 * 1024,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE,
   is_winnt:false,
   is_server:false,
@@ -246,6 +250,7 @@ static NO_COPY wincaps wincap_98 = {
 static NO_COPY wincaps wincap_98se = {
   lock_file_highword:0x0,
   chunksize:32 * 1024 * 1024,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE,
   is_winnt:false,
   is_server:false,
@@ -304,6 +309,7 @@ static NO_COPY wincaps wincap_98se = {
 static NO_COPY wincaps wincap_me = {
   lock_file_highword:0x0,
   chunksize:32 * 1024 * 1024,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE,
   is_winnt:false,
   is_server:false,
@@ -362,6 +368,7 @@ static NO_COPY wincaps wincap_me = {
 static NO_COPY wincaps wincap_nt3 = {
   lock_file_highword:UINT32_MAX,
   chunksize:0,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
   is_winnt:true,
   is_server:false,
@@ -420,6 +427,7 @@ static NO_COPY wincaps wincap_nt3 = {
 static NO_COPY wincaps wincap_nt4 = {
   lock_file_highword:UINT32_MAX,
   chunksize:0,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
   is_winnt:true,
   is_server:false,
@@ -478,6 +486,7 @@ static NO_COPY wincaps wincap_nt4 = {
 static NO_COPY wincaps wincap_nt4sp4 = {
   lock_file_highword:UINT32_MAX,
   chunksize:0,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
   is_winnt:true,
   is_server:false,
@@ -536,6 +545,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
 static NO_COPY wincaps wincap_2000 = {
   lock_file_highword:UINT32_MAX,
   chunksize:0,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
   is_winnt:true,
   is_server:false,
@@ -594,6 +604,7 @@ static NO_COPY wincaps wincap_2000 = {
 static NO_COPY wincaps wincap_xp = {
   lock_file_highword:UINT32_MAX,
   chunksize:0,
+  heapslop:0x0,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
   is_winnt:true,
   is_server:false,
@@ -652,6 +663,7 @@ static NO_COPY wincaps wincap_xp = {
 static NO_COPY wincaps wincap_2003 = {
   lock_file_highword:UINT32_MAX,
   chunksize:0,
+  heapslop:0x4,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
   is_winnt:true,
   is_server:true,
@@ -710,6 +722,7 @@ static NO_COPY wincaps wincap_2003 = {
 static NO_COPY wincaps wincap_vista = {
   lock_file_highword:UINT32_MAX,
   chunksize:0,
+  heapslop:0x4,
   shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
   is_winnt:true,
   is_server:true,
index 0f1b95a15b5e1034025a170d253a9374d6b5dc73..bbd58a60b13ac1e25e86c37222f7ecdee5cd988b 100644 (file)
@@ -15,6 +15,7 @@ struct wincaps
 {
   DWORD    lock_file_highword;
   DWORD    chunksize;
+  DWORD    heapslop;
   int      shared;
   unsigned is_winnt                                     : 1;
   unsigned is_server                                    : 1;
@@ -89,6 +90,7 @@ public:
 
   DWORD IMPLEMENT (lock_file_highword)
   DWORD IMPLEMENT (chunksize)
+  DWORD IMPLEMENT (heapslop)
   int   IMPLEMENT (shared)
   bool  IMPLEMENT (is_winnt)
   bool  IMPLEMENT (is_server)
This page took 0.04625 seconds and 5 git commands to generate.