Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-10-22 20:18:55 +0400
committerChristopher Faylor <me@cgf.cx>2002-10-22 20:18:55 +0400
commit1cc651ecafae07b9ed6edff9952e2b31f0503d0a (patch)
tree682ab1ca541b857ae9440cec58d23fd61575d35a
parent5ec14fe40ae1a6b11d27b975feca1b20de435467 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog18
-rw-r--r--winsup/cygwin/cygheap.cc2
-rw-r--r--winsup/cygwin/cygheap.h15
-rw-r--r--winsup/cygwin/dcrt0.cc4
-rw-r--r--winsup/cygwin/dll_init.cc6
-rw-r--r--winsup/cygwin/fork.cc2
-rw-r--r--winsup/cygwin/heap.cc95
-rw-r--r--winsup/cygwin/heap.h5
-rw-r--r--winsup/cygwin/shared.cc70
-rw-r--r--winsup/cygwin/shared_info.h4
-rw-r--r--winsup/cygwin/strace.cc10
11 files changed, 142 insertions, 89 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f84535e6c..a204f9f81 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index e4ea673d0..0bfb06a7e 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -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)
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index fd784ae95..703c1d1dc 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -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;
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index febb2004e..89c9a4456 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -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 */
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index 592381cde..76e26fe6e 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -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",
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 485bd17ea..165c794ca 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -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);
diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc
index c850a796c..19ce3f875 100644
--- a/winsup/cygwin/heap.cc
+++ b/winsup/cygwin/heap.cc
@@ -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;
}
diff --git a/winsup/cygwin/heap.h b/winsup/cygwin/heap.h
index bcea4bae0..b497dd3a4 100644
--- a/winsup/cygwin/heap.h
+++ b/winsup/cygwin/heap.h
@@ -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))
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index ba370f834..8aaa3c655 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -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;
}
diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h
index c93fd6762..0156763e6 100644
--- a/winsup/cygwin/shared_info.h
+++ b/winsup/cygwin/shared_info.h
@@ -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;
diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc
index cb367afeb..26f155aaa 100644
--- a/winsup/cygwin/strace.cc
+++ b/winsup/cygwin/strace.cc
@@ -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, "**********************************************");
}
}