diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2006-10-31 18:41:16 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2006-10-31 18:41:16 +0000 |
commit | c2b10dc4d83b4bfba357eb6cfc4b7698dc8fef1c (patch) | |
tree | 90de2c2c6336df77e7916882eac81edc70b208ec /winsup/cygwin/heap.cc | |
parent | 9740f34d11c458fd7a07a025810422a6db1ad374 (diff) | |
download | cygnal-c2b10dc4d83b4bfba357eb6cfc4b7698dc8fef1c.tar.gz cygnal-c2b10dc4d83b4bfba357eb6cfc4b7698dc8fef1c.tar.bz2 cygnal-c2b10dc4d83b4bfba357eb6cfc4b7698dc8fef1c.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/heap.cc')
-rw-r--r-- | winsup/cygwin/heap.cc | 27 |
1 files changed, 22 insertions, 5 deletions
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 { |