summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/cygheap.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-06-01 03:46:56 +0000
committerChristopher Faylor <me@cgf.cx>2005-06-01 03:46:56 +0000
commitce95c6407ef6ab1a60a1b1e2cd62ef4ae2081174 (patch)
tree6d083de1286c20546e090d2d62a45f918182b3af /winsup/cygwin/cygheap.cc
parent302cb8165e957ac12528c221f263b358c859c831 (diff)
downloadcygnal-ce95c6407ef6ab1a60a1b1e2cd62ef4ae2081174.tar.gz
cygnal-ce95c6407ef6ab1a60a1b1e2cd62ef4ae2081174.tar.bz2
cygnal-ce95c6407ef6ab1a60a1b1e2cd62ef4ae2081174.zip
* child_info.h (child_info::cygheap_h): Delete.
(child_info::dwProcessId): New field. * cygheap.cc (init_cheap): Delete. (dup_now): Ditto. (cygheap_setup_for_child): Ditto. (cygheap_setup_for_child_cleanup): Ditto. (cygheap_fixup_in_child): Simplify. Use new "child_copy" function to copy heap from parent. (_csbrk): Don't attempt allocation if within cygheap section. Fix so that more than one allocation will succeed. (cygheap_init): Reset possibly-nonzero region to zero. * cygheap.h (cygheap_setup_for_child): Delete declaration. (cygheap_setup_for_child_cleanup): Ditto. (cygheap_start): Define as an array. * cygwin.sc: Modernize. Remove unneeded sections. Define cygheap here. * dcrt0.cc (do_exit): Reflect argument change to close_all_files. * dtable.cc (dtable::vfork_parent_restore): Ditto. * dtable.h: Ditto. * fhandler.h: Ditto. * fork.cc (fork_copy): Call ReadProcessMemory if there is no thread (indicating that we're execing). (fork_child): Don't mess with hParent. (fork_parent): Remove hParent stuff. It happens earlier now. Remove call to cygheap_setup_for_child* stuff. (fork): Put child_info_stuff in grouped structure. Issue error if parent handle is not set. (child_copy): New function. * sigproc.cc (child_info::child_info): Put cygheap settings here. Set parent handle. (child_info::~child_info): Close parent handle if it exists. * spawn.cc (spawn_guts): Reorganize so that ciresrv is allocated at only the last minute so that cygheap changes are reflected. Delete cygheap_setup* calls. * syscalls.cc (close_all_files): Add an argument to flag when the fd entry should be released. * winsup.h (close_all_files): Add an argument to close_all_files declaration. Declare child_copy.
Diffstat (limited to 'winsup/cygwin/cygheap.cc')
-rw-r--r--winsup/cygwin/cygheap.cc195
1 files changed, 48 insertions, 147 deletions
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 369501131..5e85a074f 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -22,12 +22,16 @@
#include "heap.h"
#include "sync.h"
#include "sigproc.h"
+#include "pinfo.h"
+#include <unistd.h>
init_cygheap NO_COPY *cygheap;
void NO_COPY *cygheap_max;
+extern "C" char _cygheap_mid[] __attribute__((section(".cygheap")));
+extern "C" char _cygheap_end[] __attribute__((section(".cygheap_end")));
+
static NO_COPY muto cygheap_protect;
-static NO_COPY DWORD reserve_sz;
struct cygheap_entry
{
@@ -44,141 +48,20 @@ struct cygheap_entry
#define MVMAP_OPTIONS (FILE_MAP_WRITE)
extern "C" {
-static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
-}
-
-static void
-init_cheap ()
-{
-#ifndef DEBUGGING
- reserve_sz = CYGHEAPSIZE;
-#else
- char buf[80];
- DWORD initial_sz = 0;
- if (!GetEnvironmentVariable ("CYGWIN_HEAPSIZE", buf, sizeof buf - 1))
- initial_sz = reserve_sz = CYGHEAPSIZE;
- else
- {
- initial_sz = reserve_sz = atoi (buf);
- small_printf ("using cygheap size %d\n", reserve_sz);
- }
-#endif
- do
- if ((cygheap = (init_cygheap *) VirtualAlloc ((void *) &_cygheap_start,
- reserve_sz, MEM_RESERVE,
- PAGE_NOACCESS)))
- break;
- while ((reserve_sz -= 2 * (1024 * 1024)) >= CYGHEAPSIZE_MIN);
-#ifdef DEBUGGING
- if (reserve_sz != initial_sz)
- small_printf ("reset initial cygheap size to %u\n", reserve_sz);
-#endif
- if (!cygheap)
- {
- MEMORY_BASIC_INFORMATION m;
- if (!VirtualQuery ((LPCVOID) &_cygheap_start, &m, sizeof m))
- system_printf ("couldn't get memory info, %E");
- system_printf ("Couldn't reserve %d bytes of space for cygwin's heap, %E",
- reserve_sz);
- api_fatal ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
- m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
- }
- cygheap_max = cygheap;
-}
-
-static void dup_now (void *, child_info *, unsigned) __attribute__ ((regparm(3)));
-static void
-dup_now (void *newcygheap, child_info *ci, unsigned n)
-{
- if (!VirtualAlloc (newcygheap, n, MEM_COMMIT, PAGE_READWRITE))
- api_fatal ("couldn't allocate new cygwin heap %p, %d for child, %E",
- newcygheap, n);
- memcpy (newcygheap, cygheap, n);
-}
-
-void *__stdcall
-cygheap_setup_for_child (child_info *ci, bool dup_later)
-{
- void *newcygheap;
- cygheap_protect.acquire ();
- unsigned n = (char *) cygheap_max - (char *) cygheap;
- unsigned size = reserve_sz;
- if (size < n)
- size = n + (128 * 1024);
- ci->cygheap_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_none,
- CFMAP_OPTIONS, 0, size, NULL);
- if (!ci->cygheap_h)
- api_fatal ("Couldn't create heap for child, size %d, %E", size);
- newcygheap = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL);
- if (!newcygheap)
- api_fatal ("couldn't map space for new cygheap, %E");
- ProtectHandle1INH (ci->cygheap_h, passed_cygheap_h);
- if (!dup_later)
- dup_now (newcygheap, ci, n);
- cygheap_protect.release ();
- ci->cygheap = cygheap;
- ci->cygheap_max = cygheap_max;
- ci->cygheap_reserve_sz = size;
- return newcygheap;
-}
-
-void __stdcall
-cygheap_setup_for_child_cleanup (void *newcygheap, child_info *ci,
- bool dup_it_now)
-{
- if (dup_it_now)
- {
- /* NOTE: There is an assumption here that cygheap_max has not changed
- between the time that cygheap_setup_for_child was called and now.
- Make sure that this is a correct assumption. */
- cygheap_protect.acquire ();
- dup_now (newcygheap, ci, (char *) cygheap_max - (char *) cygheap);
- cygheap_protect.release ();
- }
- UnmapViewOfFile (newcygheap);
- ForceCloseHandle1 (ci->cygheap_h, passed_cygheap_h);
+static void __stdcall _cfree (void *) __attribute__((regparm(1)));
+static void *__stdcall _csbrk (int);
}
/* Called by fork or spawn to reallocate cygwin heap */
void __stdcall
cygheap_fixup_in_child (bool execed)
{
- cygheap = child_proc_info->cygheap;
- cygheap_max = child_proc_info->cygheap_max;
- void *addr = !wincap.map_view_of_file_ex_sucks () ? cygheap : NULL;
- void *newaddr;
-
- newaddr = MapViewOfFileEx (child_proc_info->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, addr);
- reserve_sz = child_proc_info->cygheap_reserve_sz;
- if (newaddr != cygheap)
- {
- if (!newaddr)
- newaddr = MapViewOfFileEx (child_proc_info->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL);
- DWORD n = (DWORD) cygheap_max - (DWORD) cygheap;
- /* Reserve cygwin heap in same spot as parent */
- if (!VirtualAlloc (cygheap, reserve_sz, MEM_RESERVE, PAGE_NOACCESS))
- {
- MEMORY_BASIC_INFORMATION m;
- memset (&m, 0, sizeof m);
- if (!VirtualQuery ((LPCVOID) cygheap, &m, sizeof m))
- system_printf ("couldn't get memory info, %E");
-
- system_printf ("Couldn't reserve %d bytes of space for cygwin's heap (%p <%p>) in child, %E",
- reserve_sz, cygheap, newaddr);
- api_fatal ("m.AllocationBase %p, m.BaseAddress %p, m.RegionSize %p, m.State %p\n",
- m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
- }
-
- /* Allocate same amount of memory as parent */
- if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
- api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
- cygheap, n);
- memcpy (cygheap, newaddr, n);
- UnmapViewOfFile (newaddr);
- }
-
- ForceCloseHandle1 (child_proc_info->cygheap_h, passed_cygheap_h);
-
+ cygheap_max = child_proc_info->cygheap;
+ cygheap = (init_cygheap *) cygheap_max;
+ _csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap);
+ child_copy (child_proc_info->parent, child_proc_info->dwProcessId, "cygheap", cygheap, cygheap_max);
+ if (execed)
+ CloseHandle (child_proc_info->parent);
cygheap_init ();
debug_fixup_after_fork_exec ();
@@ -222,30 +105,42 @@ init_cygheap::close_ctty ()
#endif
}
-#define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
+#define nextpage(x) ((char *) (((DWORD) ((char *) x + granmask)) & ~granmask))
+#define allocsize(x) ((DWORD) nextpage (x))
+#ifdef DEBUGGING
+#define somekinda_printf debug_printf
+#else
+#define somekinda_printf malloc_printf
+#endif
static void *__stdcall
_csbrk (int sbs)
{
void *prebrk = cygheap_max;
- void *prebrka = pagetrunc (prebrk);
+ size_t granmask = getshmlba () - 1;
+ char *newbase = nextpage (prebrk);
cygheap_max = (char *) cygheap_max + sbs;
- if (!sbs || (prebrk != prebrka && prebrka == pagetrunc (cygheap_max)))
+ if (!sbs || (newbase > cygheap_max) || (cygheap_max < _cygheap_end))
/* nothing to do */;
- else if (!VirtualAlloc (prebrk, (DWORD) sbs, MEM_COMMIT, PAGE_READWRITE))
+ else
{
-#ifdef DEBUGGING
- system_printf ("couldn't commit memory for cygwin heap, prebrk %p, size %d, heapsize now %d, max heap size %u, %E",
- prebrk, sbs, (char *) cygheap_max - (char *) cygheap,
- reserve_sz);
-#else
- malloc_printf ("couldn't commit memory for cygwin heap, prebrk %p, size %d, heapsize now %d, max heap size %u, %E",
- prebrk, sbs, (char *) cygheap_max - (char *) cygheap,
- reserve_sz);
-#endif
- __seterrno ();
- cygheap_max = (char *) cygheap_max - sbs;
- return NULL;
+ if (prebrk <= _cygheap_end)
+ newbase = _cygheap_end;
+
+ DWORD adjsbs = allocsize ((char *) cygheap_max - newbase);
+ if (!VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
+ {
+ MEMORY_BASIC_INFORMATION m;
+ if (!VirtualQuery (newbase, &m, sizeof m))
+ system_printf ("couldn't get memory info, %E");
+ somekinda_printf ("Couldn't reserve/commit %d bytes of space for cygwin's heap, %E",
+ adjsbs);
+ somekinda_printf ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
+ m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
+ __seterrno ();
+ cygheap_max = (char *) cygheap_max - sbs;
+ return NULL;
+ }
}
return prebrk;
@@ -257,7 +152,13 @@ cygheap_init ()
cygheap_protect.init ("cygheap_protect");
if (!cygheap)
{
- init_cheap ();
+#if 1
+ cygheap = (init_cygheap *) memset (_cygheap_start, 0, _cygheap_mid - _cygheap_start);
+#else
+ cygheap = (init_cygheap *) _cygheap_start;
+#endif
+
+ cygheap_max = cygheap;
(void) _csbrk (sizeof (*cygheap));
}
if (!cygheap->fdtab)