From 3ceccd2adb2e3c4d6a53bd23c0a090cdd227b737 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 8 Nov 2006 10:00:06 +0000 Subject: [PATCH] * dtable.cc (build_fh_pc): Add missing DEV_SD1_MAJOR case (Thanks to Joe Loh for noticing). * 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. --- winsup/cygwin/ChangeLog | 20 ++++++++++++++++++++ winsup/cygwin/cygheap.h | 1 + winsup/cygwin/dtable.cc | 3 ++- winsup/cygwin/heap.cc | 27 ++++++++++++++++++++++----- winsup/cygwin/mmap.cc | 6 ++++-- winsup/cygwin/shared.cc | 31 ++++++++++++++++++++++++++++++- winsup/cygwin/shared_info.h | 6 ++++-- winsup/cygwin/wincap.cc | 13 +++++++++++++ winsup/cygwin/wincap.h | 2 ++ 9 files changed, 98 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 45ec58bfe..87de82a4d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +2006-11-06 Corinna Vinschen + + * dtable.cc (build_fh_pc): Add missing DEV_SD1_MAJOR case (Thanks to + Joe Loh for noticing). + +2006-10-31 Corinna Vinschen + + * 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-27 Corinna Vinschen * dcrt0.cc (__api_fatal): Drop spare argument to __small_sprintf. diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 0afe1620d..d5a4893de 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/dtable.cc b/winsup/cygwin/dtable.cc index fbec8c9e6..24777a62a 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -1,7 +1,7 @@ /* dtable.cc: file descriptor support. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005 Red Hat, Inc. + 2005, 2006 Red Hat, Inc. This file is part of Cygwin. @@ -383,6 +383,7 @@ build_fh_pc (path_conv& pc) case DEV_FLOPPY_MAJOR: case DEV_CDROM_MAJOR: case DEV_SD_MAJOR: + case DEV_SD1_MAJOR: fh = cnew (fhandler_dev_floppy) (); break; case DEV_TAPE_MAJOR: 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 97966515e..ea38dd38d 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, @@ -1649,7 +1650,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 c491708e3..46209135f 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -259,6 +259,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 () { @@ -285,7 +312,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 821807641..fa249c0df 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -142,9 +142,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 @@ -155,11 +155,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) -- 2.43.5