OSDN Git Service

* cygheap.cc (cygheap_fixup_in_child): Use user_heap element in cygheap.
authorcgf <cgf>
Tue, 22 Oct 2002 16:18:55 +0000 (16:18 +0000)
committercgf <cgf>
Tue, 22 Oct 2002 16:18:55 +0000 (16:18 +0000)
(init_cheap): Ditto for declaration.
* fork.cc (fork_parent): Use user_heap element in cygheap.
* heap.h (inheap): Ditto.
* heap.cc (sbrk): Ditto.
(heap_init): Ditto.  Reorganize to shrink heap chunk as required and record new
value in cygheap.
* dcrt0.cc (dll_crt0_1): More "move the cygthread init" games.
* shared.cc (open_shared): Rework memory protection to properly deal with
relocated shared segment.
(shared_info::heap_chunk_size): Rename element to 'heap_chunk'.
* shared_info.h (shared_info): Ditto for declaration.
* strace.cc (strace::hello): Report on heap chunk size from cygheap since it
may shrink.

winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap.h
winsup/cygwin/dcrt0.cc
winsup/cygwin/dll_init.cc
winsup/cygwin/fork.cc
winsup/cygwin/heap.cc
winsup/cygwin/heap.h
winsup/cygwin/shared.cc
winsup/cygwin/shared_info.h
winsup/cygwin/strace.cc

index f84535e..a204f9f 100644 (file)
@@ -1,3 +1,21 @@
+2002-10-22  Christopher Faylor  <cgf@redhat.com>
+
+       * cygheap.cc (cygheap_fixup_in_child): Use user_heap element in
+       cygheap.
+       (init_cheap): Ditto for declaration.
+       * fork.cc (fork_parent): Use user_heap element in cygheap.
+       * heap.h (inheap): Ditto.
+       * heap.cc (sbrk): Ditto.
+       (heap_init): Ditto.  Reorganize to shrink heap chunk as required and
+       record new value in cygheap.
+       * dcrt0.cc (dll_crt0_1): More "move the cygthread init" games.
+       * shared.cc (open_shared): Rework memory protection to properly deal
+       with relocated shared segment.
+       (shared_info::heap_chunk_size): Rename element to 'heap_chunk'.
+       * shared_info.h (shared_info): Ditto for declaration.
+       * strace.cc (strace::hello): Report on heap chunk size from cygheap
+       since it may shrink.
+
 2002-10-20  Christopher Faylor  <cgf@redhat.com>
 
        Change _function() to function() throughout.
index e4ea673..0bfb06a 100644 (file)
@@ -156,7 +156,7 @@ cygheap_fixup_in_child (bool execed)
 
   if (execed)
     {
-      cygheap->heapbase = NULL;                /* We can allocate the heap anywhere */
+      cygheap->user_heap.base = NULL;          /* We can allocate the heap anywhere */
       /* Walk the allocated memory chain looking for orphaned memory from
         previous execs */
       for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev)
index fd784ae..703c1d1 100644 (file)
@@ -198,18 +198,21 @@ struct cygheap_debug
 };
 #endif
 
+struct user_heap_info
+{
+  void *base;
+  void *ptr;
+  void *top;
+  unsigned chunk;
+};
+
 struct init_cygheap
 {
   _cmalloc_entry *chain;
   char *buckets[32];
-  struct /* User heap stuff. */
-    {
-      void *heapbase;
-      void *heapptr;
-      void *heaptop;
-    };
   cygheap_root root;
   cygheap_user user;
+  user_heap_info user_heap;
   mode_t umask;
   HANDLE shared_h;
   HANDLE console_h;
index febb200..89c9a44 100644 (file)
@@ -585,11 +585,11 @@ dll_crt0_1 ()
        {
          case _PROC_FORK:
            alloc_stack (fork_info);
-           cygthread::init ();
            cygheap_fixup_in_child (0);
-           close_ppid_handle = !!child_proc_info->pppid_handle;
            memory_init ();
+           cygthread::init ();
            set_myself (mypid);
+           close_ppid_handle = !!child_proc_info->pppid_handle;
            break;
          case _PROC_SPAWN:
            /* Have to delay closes until after cygheap is setup */
index 592381c..76e26fe 100644 (file)
@@ -261,8 +261,10 @@ release_upto (const char *name, DWORD here)
       {
        size = mb.RegionSize;
        if (!(mb.State == MEM_RESERVE && mb.AllocationProtect == PAGE_NOACCESS &&
-           (((void *) start < cygheap->heapbase || (void *) start > cygheap->heaptop) &&
-            ((void *) start < (void *) cygheap || (void *) start > (void *) ((char *) cygheap + CYGHEAPSIZE)))))
+           (((void *) start < cygheap->user_heap.base
+             || (void *) start > cygheap->user_heap.top) &&
+            ((void *) start < (void *) cygheap 
+             | (void *) start > (void *) ((char *) cygheap + CYGHEAPSIZE)))))
          continue;
        if (!VirtualFree ((void *) start, 0, MEM_RELEASE))
          api_fatal ("couldn't release memory %p(%d) for '%s' alignment, %E\n",
index 485bd17..165c794 100644 (file)
@@ -551,7 +551,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
   rc = fork_copy (pi, "user/cygwin data",
                  user_data->data_start, user_data->data_end,
                  user_data->bss_start, user_data->bss_end,
-                 cygheap->heapbase, cygheap->heapptr,
+                 cygheap->user_heap.base, cygheap->user_heap.ptr,
                  stack_here, ch.stackbottom,
                  dll_data_start, dll_data_end,
                  dll_bss_start, dll_bss_end, NULL);
index c850a79..19ce3f8 100644 (file)
@@ -20,6 +20,8 @@ details. */
 #include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
+#include "registry.h"
+#include "cygwin_version.h"
 
 #define assert(x)
 
@@ -27,6 +29,8 @@ static unsigned page_const;
 
 extern "C" size_t getpagesize ();
 
+#define MINHEAP_SIZE (4 * 1024 * 1024)
+
 /* Initialize the heap at process start up.  */
 
 void
@@ -36,19 +40,40 @@ heap_init ()
      as our parent.  If not, we don't care where it ends up.  */
 
   page_const = system_info.dwPageSize;
-  if (cygheap->heapbase)
+  if (!cygheap->user_heap.base)
+    {
+      cygheap->user_heap.chunk = cygwin_shared->heap_chunk_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, MEM_RESERVE, 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);
+    }
+  else
     {
-      DWORD chunk = cygwin_shared->heap_chunk_size (); /* allocation chunk */
+      DWORD chunk = cygheap->user_heap.chunk;  /* allocation chunk */
       /* total size commited in parent */
-      DWORD allocsize = (char *) cygheap->heaptop - (char *) cygheap->heapbase;
+      DWORD allocsize = (char *) cygheap->user_heap.top -
+                       (char *) cygheap->user_heap.base;
       /* round up by chunk size */
       DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
 
       /* Loop until we've managed to reserve an adequate amount of memory. */
       char *p;
+MEMORY_BASIC_INFORMATION m;
+(void) VirtualQuery (cygheap->user_heap.base, &m, sizeof (m));
       for (;;)
        {
-         p = (char *) VirtualAlloc (cygheap->heapbase, reserve_size,
+         p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size,
                                     MEM_RESERVE, PAGE_READWRITE);
          if (p)
            break;
@@ -56,27 +81,25 @@ heap_init ()
            break;
        }
       if (p == NULL)
-       api_fatal ("1. unable to allocate heap %p, heap_chunk_size %d, pid %d, %E",
-                  cygheap->heapbase, cygwin_shared->heap_chunk_size (), myself->pid);
-      if (p != cygheap->heapbase)
-       api_fatal ("heap allocated but not at %p", cygheap->heapbase);
-      if (!VirtualAlloc (cygheap->heapbase, allocsize, MEM_COMMIT, PAGE_READWRITE))
+{
+system_printf ("unable to allocate heap %p, chunk %u, reserve %u, alloc %u, %E",
+cygheap->user_heap.base, cygheap->user_heap.chunk,
+reserve_size, allocsize);
+system_printf ("base %p mem alloc base %p, state %p, size %d, %E",
+cygheap->user_heap.base, m.AllocationBase, m.State, m.RegionSize);
+error_start_init ("h:/gdbtest/gdb.exe < con > con"); try_to_debug ();
+       api_fatal ("unable to allocate heap %p, chunk %u, reserve %u, alloc %u, %E",
+                  cygheap->user_heap.base, cygheap->user_heap.chunk,
+                  reserve_size, allocsize);
+}
+      if (p != cygheap->user_heap.base)
+       api_fatal ("heap allocated but not at %p", cygheap->user_heap.base);
+      if (!VirtualAlloc (cygheap->user_heap.base, allocsize, MEM_COMMIT, PAGE_READWRITE))
        api_fatal ("MEM_COMMIT failed, %E");
     }
-  else
-    {
-      /* Initialize page mask and default heap size.  Preallocate a heap
-       * to assure contiguous memory.  */
-      cygheap->heapptr = cygheap->heaptop = cygheap->heapbase =
-       VirtualAlloc (NULL, cygwin_shared->heap_chunk_size (), MEM_RESERVE,
-                    PAGE_NOACCESS);
-      if (cygheap->heapbase == NULL)
-       api_fatal ("2. unable to allocate heap, heap_chunk_size %d, %E",
-                  cygwin_shared->heap_chunk_size ());
-    }
 
-  debug_printf ("heap base %p, heap top %p", cygheap->heapbase,
-               cygheap->heaptop);
+  debug_printf ("heap base %p, heap top %p", cygheap->user_heap.base,
+               cygheap->user_heap.top);
   page_const--;
   malloc_init ();
 }
@@ -93,43 +116,43 @@ sbrk (int n)
   unsigned commitbytes, newbrksize;
 
   if (n == 0)
-    return cygheap->heapptr;                   /* Just wanted to find current cygheap->heapptr address */
+    return cygheap->user_heap.ptr;                     /* Just wanted to find current cygheap->user_heap.ptr address */
 
-  newbrk = (char *) cygheap->heapptr + n;      /* Where new cygheap->heapptr will be */
+  newbrk = (char *) cygheap->user_heap.ptr + n;        /* Where new cygheap->user_heap.ptr will be */
   newtop = (char *) pround (newbrk);           /* Actual top of allocated memory -
                                                   on page boundary */
 
-  if (newtop == cygheap->heaptop)
+  if (newtop == cygheap->user_heap.top)
     goto good;
 
   if (n < 0)
     {                                          /* Freeing memory */
-      assert (newtop < cygheap->heaptop);
-      n = (char *) cygheap->heaptop - newtop;
+      assert (newtop < cygheap->user_heap.top);
+      n = (char *) cygheap->user_heap.top - newtop;
       if (VirtualFree (newtop, n, MEM_DECOMMIT)) /* Give it back to OS */
        goto good;                              /*  Didn't take */
       else
        goto err;
     }
 
-  assert (newtop > cygheap->heaptop);
+  assert (newtop > cygheap->user_heap.top);
 
   /* Need to grab more pages from the OS.  If this fails it may be because
    * we have used up previously reserved memory.  Or, we're just plumb out
    * of memory.  */
-  commitbytes = pround (newtop - (char *) cygheap->heaptop);
-  if (VirtualAlloc (cygheap->heaptop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)
+  commitbytes = pround (newtop - (char *) cygheap->user_heap.top);
+  if (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)
     goto good;
 
   /* Couldn't allocate memory.  Maybe we can reserve some more.
      Reserve either the maximum of the standard cygwin_shared->heap_chunk_size () or the requested
      amount.  Then attempt to actually allocate it.  */
 
-  if ((newbrksize = cygwin_shared->heap_chunk_size ()) < commitbytes)
+  if ((newbrksize = cygheap->user_heap.chunk) < commitbytes)
     newbrksize = commitbytes;
 
-  if ((VirtualAlloc (cygheap->heaptop, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) &&
-      (VirtualAlloc (cygheap->heaptop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL))
+  if ((VirtualAlloc (cygheap->user_heap.top, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) &&
+      (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL))
     goto good;
 
 err:
@@ -137,8 +160,8 @@ err:
   return (void *) -1;
 
 good:
-  void *oldbrk = cygheap->heapptr;
-  cygheap->heapptr = newbrk;
-  cygheap->heaptop = newtop;
+  void *oldbrk = cygheap->user_heap.ptr;
+  cygheap->user_heap.ptr = newbrk;
+  cygheap->user_heap.top = newtop;
   return oldbrk;
 }
index bcea4ba..b497dd3 100644 (file)
@@ -15,5 +15,6 @@ void heap_init ();
 void malloc_init ();
 
 #define inheap(s) \
-  (cygheap->heapptr && s && ((char *) (s) >= (char *) cygheap->heapbase) \
-   && ((char *) (s) <= (char *) cygheap->heaptop))
+  (cygheap->user_heap.ptr && s \
+   && ((char *) (s) >= (char *) cygheap->user_heap.base) \
+   && ((char *) (s) <= (char *) cygheap->user_heap.top))
index ba370f8..8aaa3c6 100644 (file)
@@ -47,28 +47,29 @@ shared_name (const char *str, int num)
 #define page_const (65535)
 #define pround(n) (((size_t) (n) + page_const) & ~page_const)
 
+static char *offsets[] =
+{
+  (char *) cygwin_shared_address,
+  (char *) cygwin_shared_address
+    + pround (sizeof (shared_info)),
+  (char *) cygwin_shared_address
+    + pround (sizeof (shared_info))
+    + pround (sizeof (mount_info)),
+  (char *) cygwin_shared_address
+    + pround (sizeof (shared_info))
+    + pround (sizeof (mount_info))
+    + pround (sizeof (console_state)),
+  (char *) cygwin_shared_address
+    + pround (sizeof (shared_info))
+    + pround (sizeof (mount_info))
+    + pround (sizeof (console_state))
+    + pround (sizeof (_pinfo))
+};
+
 void * __stdcall
 open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations m)
 {
   void *shared;
-  static char *offsets[] =
-  {
-    (char *) cygwin_shared_address,
-    (char *) cygwin_shared_address
-      + pround (sizeof (shared_info)),
-    (char *) cygwin_shared_address
-      + pround (sizeof (shared_info))
-      + pround (sizeof (mount_info)),
-    (char *) cygwin_shared_address
-      + pround (sizeof (shared_info))
-      + pround (sizeof (mount_info))
-      + pround (sizeof (console_state)),
-    (char *) cygwin_shared_address
-      + pround (sizeof (shared_info))
-      + pround (sizeof (mount_info))
-      + pround (sizeof (console_state))
-      + pround (sizeof (_pinfo))
-  };
 
   void *addr;
   if (!wincap.needs_memory_protection ())
@@ -117,16 +118,18 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat
   if (!shared)
     api_fatal ("MapViewOfFileEx '%s'(%p), %E.  Terminating.", name, shared_h);
 
-  if (m == SH_CYGWIN_SHARED)
+  if (m == SH_CYGWIN_SHARED && wincap.needs_memory_protection ())
     {
+      unsigned delta = (char *) shared - offsets[0];
+      offsets[0] = (char *) shared;
       for (int i = SH_CYGWIN_SHARED + 1; i < SH_TOTAL_SIZE; i++)
        {
-         offsets[i] += (char *) shared - offsets[0];
-         if (!VirtualAlloc (offsets[i], offsets[i + 1] - offsets[i],
-                            MEM_RESERVE, PAGE_NOACCESS))
+         unsigned size = offsets[i + 1] - offsets[i];
+         offsets[i] += delta;
+         if (!VirtualAlloc (offsets[i], size, MEM_RESERVE, PAGE_NOACCESS))
            continue;  /* oh well */
-         offsets[0] = (char *) shared;
        }
+      offsets[SH_TOTAL_SIZE] += delta;
 
 #if 0
       if (!child_proc_info && wincap.needs_memory_protection ())
@@ -137,9 +140,6 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat
 
   debug_printf ("name %s, shared %p (wanted %p), h %p", name, shared, addr, shared_h);
 
-  /* FIXME: I couldn't find anywhere in the documentation a note about
-     whether the memory is initialized to zero.  The code assumes it does
-     and since this part seems to be working, we'll leave it as is.  */
   return shared;
 }
 
@@ -229,7 +229,7 @@ memory_init ()
 unsigned
 shared_info::heap_chunk_size ()
 {
-  if (!initial_heap_size)
+  if (!heap_chunk)
     {
       /* Fetch misc. registry entries.  */
 
@@ -240,20 +240,20 @@ shared_info::heap_chunk_size ()
       /* FIXME: We should not be restricted to a fixed size heap no matter
       what the fixed size is. */
 
-      initial_heap_size = reg.get_int ("heap_chunk_in_mb", 0);
-      if (!initial_heap_size) {
+      heap_chunk = reg.get_int ("heap_chunk_in_mb", 0);
+      if (!heap_chunk) {
        reg_key r1 (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE",
                    CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
                    CYGWIN_INFO_CYGWIN_REGISTRY_NAME, NULL);
-        initial_heap_size = reg.get_int ("heap_chunk_in_mb", 384);
+        heap_chunk = reg.get_int ("heap_chunk_in_mb", 384);
       }
 
-      if (initial_heap_size < 4)
-       initial_heap_size = 4 * 1024 * 1024;
+      if (heap_chunk < 4)
+       heap_chunk = 4 * 1024 * 1024;
       else
-       initial_heap_size <<= 20;
-      debug_printf ("fixed heap size is %u", initial_heap_size);
+       heap_chunk <<= 20;
+      debug_printf ("fixed heap size is %u", heap_chunk);
     }
 
-  return initial_heap_size;
+  return heap_chunk;
 }
index c93fd67..0156763 100644 (file)
@@ -138,7 +138,7 @@ public:
 
 #define SHARED_INFO_CB 47112
 
-#define CURR_SHARED_MAGIC 0xd9e0bc22U
+#define CURR_SHARED_MAGIC 0x359218a2U
 
 /* NOTE: Do not make gratuitous changes to the names or organization of the
    below class.  The layout is checksummed to determine compatibility between
@@ -148,7 +148,7 @@ class shared_info
   DWORD version;
   DWORD cb;
  public:
-  unsigned initial_heap_size;
+  unsigned heap_chunk;
   DWORD sys_mount_table_counter;
 
   tty_list tty;
index cb367af..26f155a 100644 (file)
@@ -14,12 +14,18 @@ details. */
 #include <wingdi.h>
 #include <winuser.h>
 #include <ctype.h>
+#include <errno.h>
 #include "pinfo.h"
 #include "perprocess.h"
 #include "cygwin_version.h"
 #include "hires.h"
+#include "security.h"
 #include "cygthread.h"
-#include "shared_info.h"
+#include "fhandler.h"
+#include "path.h"
+#include "dtable.h"
+#include "cygerrno.h"
+#include "cygheap.h"
 
 #define PROTECT(x) x[sizeof (x)-1] = 0
 #define CHECK(x) if (x[sizeof (x)-1] != 0) { small_printf ("array bound exceeded %d\n", __LINE__); ExitProcess (1); }
@@ -58,7 +64,7 @@ strace::hello ()
             cygwin_version.api_major, cygwin_version.api_minor);
       prntf (1, NULL, "DLL build:    %s", cygwin_version.dll_build_date);
       prntf (1, NULL, "OS version:   Windows %s", wincap.osname ());
-      prntf (1, NULL, "Heap size:    %u", cygwin_shared->heap_chunk_size ());
+      prntf (1, NULL, "Heap size:    %u", cygheap->user_heap.chunk);
       prntf (1, NULL, "**********************************************");
     }
 }