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:
authorCorinna Vinschen <corinna@vinschen.de>2006-10-31 21:41:16 +0300
committerCorinna Vinschen <corinna@vinschen.de>2006-10-31 21:41:16 +0300
commitc2b10dc4d83b4bfba357eb6cfc4b7698dc8fef1c (patch)
tree90de2c2c6336df77e7916882eac81edc70b208ec
parent9740f34d11c458fd7a07a025810422a6db1ad374 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog15
-rw-r--r--winsup/cygwin/cygheap.h1
-rw-r--r--winsup/cygwin/heap.cc27
-rw-r--r--winsup/cygwin/mmap.cc6
-rw-r--r--winsup/cygwin/shared.cc31
-rw-r--r--winsup/cygwin/shared_info.h6
-rw-r--r--winsup/cygwin/wincap.cc13
-rw-r--r--winsup/cygwin/wincap.h2
8 files changed, 91 insertions, 10 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index fddfd6bf7..212bbabdb 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,20 @@
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
directory attribute for reparse points to avoid mistreating.
(fhandler_base::fstat_by_name): Ditto.
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 35db5cad8..85da8f6ed 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -262,6 +262,7 @@ struct user_heap_info
void *top;
void *max;
unsigned chunk;
+ unsigned slop;
};
struct hook_chain
diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc
index 63fc93520..5278febfc 100644
--- a/winsup/cygwin/heap.cc
+++ b/winsup/cygwin/heap.cc
@@ -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
{
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 1c1afba57..31bac5869 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -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);
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index 65965b58b..4c4b7bc72 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -235,6 +235,33 @@ memory_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 ()
{
if (!heap_chunk)
@@ -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;
diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h
index ff9361605..a1a4be0db 100644
--- a/winsup/cygwin/shared_info.h
+++ b/winsup/cygwin/shared_info.h
@@ -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;
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 9c82e45a7..df6765b7b 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -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,
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 0f1b95a15..bbd58a60b 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -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)