* 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.
This commit is contained in:
Corinna Vinschen 2006-10-31 18:41:16 +00:00
parent 9740f34d11
commit c2b10dc4d8
8 changed files with 91 additions and 10 deletions

View File

@ -1,3 +1,18 @@
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

View File

@ -262,6 +262,7 @@ struct user_heap_info
void *top;
void *max;
unsigned chunk;
unsigned slop;
};
struct hook_chain

View File

@ -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
{

View File

@ -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);

View File

@ -234,6 +234,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 ()
{
@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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)