* 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:
parent
9740f34d11
commit
c2b10dc4d8
|
@ -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
|
||||
|
|
|
@ -262,6 +262,7 @@ struct user_heap_info
|
|||
void *top;
|
||||
void *max;
|
||||
unsigned chunk;
|
||||
unsigned slop;
|
||||
};
|
||||
|
||||
struct hook_chain
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue