* cygheap.cc (cygheap_fixup_in_child): Use user_heap element in cygheap.
(init_cheap): Ditto for declaration. * fork.cc (fork_parent): Use user_heap element in cygheap. * heap.h (inheap): Ditto. * heap.cc (sbrk): Ditto. (heap_init): Ditto. Reorganize to shrink heap chunk as required and record new value in cygheap. * dcrt0.cc (dll_crt0_1): More "move the cygthread init" games. * shared.cc (open_shared): Rework memory protection to properly deal with relocated shared segment. (shared_info::heap_chunk_size): Rename element to 'heap_chunk'. * shared_info.h (shared_info): Ditto for declaration. * strace.cc (strace::hello): Report on heap chunk size from cygheap since it may shrink.
This commit is contained in:
parent
5ec14fe40a
commit
1cc651ecaf
|
@ -1,3 +1,21 @@
|
|||
2002-10-22 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* cygheap.cc (cygheap_fixup_in_child): Use user_heap element in
|
||||
cygheap.
|
||||
(init_cheap): Ditto for declaration.
|
||||
* fork.cc (fork_parent): Use user_heap element in cygheap.
|
||||
* heap.h (inheap): Ditto.
|
||||
* heap.cc (sbrk): Ditto.
|
||||
(heap_init): Ditto. Reorganize to shrink heap chunk as required and
|
||||
record new value in cygheap.
|
||||
* dcrt0.cc (dll_crt0_1): More "move the cygthread init" games.
|
||||
* shared.cc (open_shared): Rework memory protection to properly deal
|
||||
with relocated shared segment.
|
||||
(shared_info::heap_chunk_size): Rename element to 'heap_chunk'.
|
||||
* shared_info.h (shared_info): Ditto for declaration.
|
||||
* strace.cc (strace::hello): Report on heap chunk size from cygheap
|
||||
since it may shrink.
|
||||
|
||||
2002-10-20 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
Change _function() to function() throughout.
|
||||
|
|
|
@ -156,7 +156,7 @@ cygheap_fixup_in_child (bool execed)
|
|||
|
||||
if (execed)
|
||||
{
|
||||
cygheap->heapbase = NULL; /* We can allocate the heap anywhere */
|
||||
cygheap->user_heap.base = NULL; /* We can allocate the heap anywhere */
|
||||
/* Walk the allocated memory chain looking for orphaned memory from
|
||||
previous execs */
|
||||
for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev)
|
||||
|
|
|
@ -198,18 +198,21 @@ struct cygheap_debug
|
|||
};
|
||||
#endif
|
||||
|
||||
struct user_heap_info
|
||||
{
|
||||
void *base;
|
||||
void *ptr;
|
||||
void *top;
|
||||
unsigned chunk;
|
||||
};
|
||||
|
||||
struct init_cygheap
|
||||
{
|
||||
_cmalloc_entry *chain;
|
||||
char *buckets[32];
|
||||
struct /* User heap stuff. */
|
||||
{
|
||||
void *heapbase;
|
||||
void *heapptr;
|
||||
void *heaptop;
|
||||
};
|
||||
cygheap_root root;
|
||||
cygheap_user user;
|
||||
user_heap_info user_heap;
|
||||
mode_t umask;
|
||||
HANDLE shared_h;
|
||||
HANDLE console_h;
|
||||
|
|
|
@ -585,11 +585,11 @@ dll_crt0_1 ()
|
|||
{
|
||||
case _PROC_FORK:
|
||||
alloc_stack (fork_info);
|
||||
cygthread::init ();
|
||||
cygheap_fixup_in_child (0);
|
||||
close_ppid_handle = !!child_proc_info->pppid_handle;
|
||||
memory_init ();
|
||||
cygthread::init ();
|
||||
set_myself (mypid);
|
||||
close_ppid_handle = !!child_proc_info->pppid_handle;
|
||||
break;
|
||||
case _PROC_SPAWN:
|
||||
/* Have to delay closes until after cygheap is setup */
|
||||
|
|
|
@ -261,8 +261,10 @@ release_upto (const char *name, DWORD here)
|
|||
{
|
||||
size = mb.RegionSize;
|
||||
if (!(mb.State == MEM_RESERVE && mb.AllocationProtect == PAGE_NOACCESS &&
|
||||
(((void *) start < cygheap->heapbase || (void *) start > cygheap->heaptop) &&
|
||||
((void *) start < (void *) cygheap || (void *) start > (void *) ((char *) cygheap + CYGHEAPSIZE)))))
|
||||
(((void *) start < cygheap->user_heap.base
|
||||
|| (void *) start > cygheap->user_heap.top) &&
|
||||
((void *) start < (void *) cygheap
|
||||
| (void *) start > (void *) ((char *) cygheap + CYGHEAPSIZE)))))
|
||||
continue;
|
||||
if (!VirtualFree ((void *) start, 0, MEM_RELEASE))
|
||||
api_fatal ("couldn't release memory %p(%d) for '%s' alignment, %E\n",
|
||||
|
|
|
@ -551,7 +551,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||
rc = fork_copy (pi, "user/cygwin data",
|
||||
user_data->data_start, user_data->data_end,
|
||||
user_data->bss_start, user_data->bss_end,
|
||||
cygheap->heapbase, cygheap->heapptr,
|
||||
cygheap->user_heap.base, cygheap->user_heap.ptr,
|
||||
stack_here, ch.stackbottom,
|
||||
dll_data_start, dll_data_end,
|
||||
dll_bss_start, dll_bss_end, NULL);
|
||||
|
|
|
@ -20,6 +20,8 @@ details. */
|
|||
#include "path.h"
|
||||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include "registry.h"
|
||||
#include "cygwin_version.h"
|
||||
|
||||
#define assert(x)
|
||||
|
||||
|
@ -27,6 +29,8 @@ static unsigned page_const;
|
|||
|
||||
extern "C" size_t getpagesize ();
|
||||
|
||||
#define MINHEAP_SIZE (4 * 1024 * 1024)
|
||||
|
||||
/* Initialize the heap at process start up. */
|
||||
|
||||
void
|
||||
|
@ -36,19 +40,40 @@ heap_init ()
|
|||
as our parent. If not, we don't care where it ends up. */
|
||||
|
||||
page_const = system_info.dwPageSize;
|
||||
if (cygheap->heapbase)
|
||||
if (!cygheap->user_heap.base)
|
||||
{
|
||||
DWORD chunk = cygwin_shared->heap_chunk_size (); /* allocation chunk */
|
||||
cygheap->user_heap.chunk = cygwin_shared->heap_chunk_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, MEM_RESERVE, 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD chunk = cygheap->user_heap.chunk; /* allocation chunk */
|
||||
/* total size commited in parent */
|
||||
DWORD allocsize = (char *) cygheap->heaptop - (char *) cygheap->heapbase;
|
||||
DWORD allocsize = (char *) cygheap->user_heap.top -
|
||||
(char *) cygheap->user_heap.base;
|
||||
/* round up by chunk size */
|
||||
DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
|
||||
|
||||
/* Loop until we've managed to reserve an adequate amount of memory. */
|
||||
char *p;
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
(void) VirtualQuery (cygheap->user_heap.base, &m, sizeof (m));
|
||||
for (;;)
|
||||
{
|
||||
p = (char *) VirtualAlloc (cygheap->heapbase, reserve_size,
|
||||
p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size,
|
||||
MEM_RESERVE, PAGE_READWRITE);
|
||||
if (p)
|
||||
break;
|
||||
|
@ -56,27 +81,25 @@ heap_init ()
|
|||
break;
|
||||
}
|
||||
if (p == NULL)
|
||||
api_fatal ("1. unable to allocate heap %p, heap_chunk_size %d, pid %d, %E",
|
||||
cygheap->heapbase, cygwin_shared->heap_chunk_size (), myself->pid);
|
||||
if (p != cygheap->heapbase)
|
||||
api_fatal ("heap allocated but not at %p", cygheap->heapbase);
|
||||
if (!VirtualAlloc (cygheap->heapbase, allocsize, MEM_COMMIT, PAGE_READWRITE))
|
||||
{
|
||||
system_printf ("unable to allocate heap %p, chunk %u, reserve %u, alloc %u, %E",
|
||||
cygheap->user_heap.base, cygheap->user_heap.chunk,
|
||||
reserve_size, allocsize);
|
||||
system_printf ("base %p mem alloc base %p, state %p, size %d, %E",
|
||||
cygheap->user_heap.base, m.AllocationBase, m.State, m.RegionSize);
|
||||
error_start_init ("h:/gdbtest/gdb.exe < con > con"); try_to_debug ();
|
||||
api_fatal ("unable to allocate heap %p, chunk %u, reserve %u, alloc %u, %E",
|
||||
cygheap->user_heap.base, cygheap->user_heap.chunk,
|
||||
reserve_size, allocsize);
|
||||
}
|
||||
if (p != cygheap->user_heap.base)
|
||||
api_fatal ("heap allocated but not at %p", cygheap->user_heap.base);
|
||||
if (!VirtualAlloc (cygheap->user_heap.base, allocsize, MEM_COMMIT, PAGE_READWRITE))
|
||||
api_fatal ("MEM_COMMIT failed, %E");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize page mask and default heap size. Preallocate a heap
|
||||
* to assure contiguous memory. */
|
||||
cygheap->heapptr = cygheap->heaptop = cygheap->heapbase =
|
||||
VirtualAlloc (NULL, cygwin_shared->heap_chunk_size (), MEM_RESERVE,
|
||||
PAGE_NOACCESS);
|
||||
if (cygheap->heapbase == NULL)
|
||||
api_fatal ("2. unable to allocate heap, heap_chunk_size %d, %E",
|
||||
cygwin_shared->heap_chunk_size ());
|
||||
}
|
||||
|
||||
debug_printf ("heap base %p, heap top %p", cygheap->heapbase,
|
||||
cygheap->heaptop);
|
||||
debug_printf ("heap base %p, heap top %p", cygheap->user_heap.base,
|
||||
cygheap->user_heap.top);
|
||||
page_const--;
|
||||
malloc_init ();
|
||||
}
|
||||
|
@ -93,43 +116,43 @@ sbrk (int n)
|
|||
unsigned commitbytes, newbrksize;
|
||||
|
||||
if (n == 0)
|
||||
return cygheap->heapptr; /* Just wanted to find current cygheap->heapptr address */
|
||||
return cygheap->user_heap.ptr; /* Just wanted to find current cygheap->user_heap.ptr address */
|
||||
|
||||
newbrk = (char *) cygheap->heapptr + n; /* Where new cygheap->heapptr will be */
|
||||
newbrk = (char *) cygheap->user_heap.ptr + n; /* Where new cygheap->user_heap.ptr will be */
|
||||
newtop = (char *) pround (newbrk); /* Actual top of allocated memory -
|
||||
on page boundary */
|
||||
|
||||
if (newtop == cygheap->heaptop)
|
||||
if (newtop == cygheap->user_heap.top)
|
||||
goto good;
|
||||
|
||||
if (n < 0)
|
||||
{ /* Freeing memory */
|
||||
assert (newtop < cygheap->heaptop);
|
||||
n = (char *) cygheap->heaptop - newtop;
|
||||
assert (newtop < cygheap->user_heap.top);
|
||||
n = (char *) cygheap->user_heap.top - newtop;
|
||||
if (VirtualFree (newtop, n, MEM_DECOMMIT)) /* Give it back to OS */
|
||||
goto good; /* Didn't take */
|
||||
else
|
||||
goto err;
|
||||
}
|
||||
|
||||
assert (newtop > cygheap->heaptop);
|
||||
assert (newtop > cygheap->user_heap.top);
|
||||
|
||||
/* Need to grab more pages from the OS. If this fails it may be because
|
||||
* we have used up previously reserved memory. Or, we're just plumb out
|
||||
* of memory. */
|
||||
commitbytes = pround (newtop - (char *) cygheap->heaptop);
|
||||
if (VirtualAlloc (cygheap->heaptop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)
|
||||
commitbytes = pround (newtop - (char *) cygheap->user_heap.top);
|
||||
if (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)
|
||||
goto good;
|
||||
|
||||
/* Couldn't allocate memory. Maybe we can reserve some more.
|
||||
Reserve either the maximum of the standard cygwin_shared->heap_chunk_size () or the requested
|
||||
amount. Then attempt to actually allocate it. */
|
||||
|
||||
if ((newbrksize = cygwin_shared->heap_chunk_size ()) < commitbytes)
|
||||
if ((newbrksize = cygheap->user_heap.chunk) < commitbytes)
|
||||
newbrksize = commitbytes;
|
||||
|
||||
if ((VirtualAlloc (cygheap->heaptop, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) &&
|
||||
(VirtualAlloc (cygheap->heaptop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL))
|
||||
if ((VirtualAlloc (cygheap->user_heap.top, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) &&
|
||||
(VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL))
|
||||
goto good;
|
||||
|
||||
err:
|
||||
|
@ -137,8 +160,8 @@ err:
|
|||
return (void *) -1;
|
||||
|
||||
good:
|
||||
void *oldbrk = cygheap->heapptr;
|
||||
cygheap->heapptr = newbrk;
|
||||
cygheap->heaptop = newtop;
|
||||
void *oldbrk = cygheap->user_heap.ptr;
|
||||
cygheap->user_heap.ptr = newbrk;
|
||||
cygheap->user_heap.top = newtop;
|
||||
return oldbrk;
|
||||
}
|
||||
|
|
|
@ -15,5 +15,6 @@ void heap_init ();
|
|||
void malloc_init ();
|
||||
|
||||
#define inheap(s) \
|
||||
(cygheap->heapptr && s && ((char *) (s) >= (char *) cygheap->heapbase) \
|
||||
&& ((char *) (s) <= (char *) cygheap->heaptop))
|
||||
(cygheap->user_heap.ptr && s \
|
||||
&& ((char *) (s) >= (char *) cygheap->user_heap.base) \
|
||||
&& ((char *) (s) <= (char *) cygheap->user_heap.top))
|
||||
|
|
|
@ -47,12 +47,8 @@ shared_name (const char *str, int num)
|
|||
#define page_const (65535)
|
||||
#define pround(n) (((size_t) (n) + page_const) & ~page_const)
|
||||
|
||||
void * __stdcall
|
||||
open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations m)
|
||||
static char *offsets[] =
|
||||
{
|
||||
void *shared;
|
||||
static char *offsets[] =
|
||||
{
|
||||
(char *) cygwin_shared_address,
|
||||
(char *) cygwin_shared_address
|
||||
+ pround (sizeof (shared_info)),
|
||||
|
@ -68,7 +64,12 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat
|
|||
+ pround (sizeof (mount_info))
|
||||
+ pround (sizeof (console_state))
|
||||
+ pround (sizeof (_pinfo))
|
||||
};
|
||||
};
|
||||
|
||||
void * __stdcall
|
||||
open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations m)
|
||||
{
|
||||
void *shared;
|
||||
|
||||
void *addr;
|
||||
if (!wincap.needs_memory_protection ())
|
||||
|
@ -117,16 +118,18 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat
|
|||
if (!shared)
|
||||
api_fatal ("MapViewOfFileEx '%s'(%p), %E. Terminating.", name, shared_h);
|
||||
|
||||
if (m == SH_CYGWIN_SHARED)
|
||||
if (m == SH_CYGWIN_SHARED && wincap.needs_memory_protection ())
|
||||
{
|
||||
unsigned delta = (char *) shared - offsets[0];
|
||||
offsets[0] = (char *) shared;
|
||||
for (int i = SH_CYGWIN_SHARED + 1; i < SH_TOTAL_SIZE; i++)
|
||||
{
|
||||
offsets[i] += (char *) shared - offsets[0];
|
||||
if (!VirtualAlloc (offsets[i], offsets[i + 1] - offsets[i],
|
||||
MEM_RESERVE, PAGE_NOACCESS))
|
||||
unsigned size = offsets[i + 1] - offsets[i];
|
||||
offsets[i] += delta;
|
||||
if (!VirtualAlloc (offsets[i], size, MEM_RESERVE, PAGE_NOACCESS))
|
||||
continue; /* oh well */
|
||||
offsets[0] = (char *) shared;
|
||||
}
|
||||
offsets[SH_TOTAL_SIZE] += delta;
|
||||
|
||||
#if 0
|
||||
if (!child_proc_info && wincap.needs_memory_protection ())
|
||||
|
@ -137,9 +140,6 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat
|
|||
|
||||
debug_printf ("name %s, shared %p (wanted %p), h %p", name, shared, addr, shared_h);
|
||||
|
||||
/* FIXME: I couldn't find anywhere in the documentation a note about
|
||||
whether the memory is initialized to zero. The code assumes it does
|
||||
and since this part seems to be working, we'll leave it as is. */
|
||||
return shared;
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ memory_init ()
|
|||
unsigned
|
||||
shared_info::heap_chunk_size ()
|
||||
{
|
||||
if (!initial_heap_size)
|
||||
if (!heap_chunk)
|
||||
{
|
||||
/* Fetch misc. registry entries. */
|
||||
|
||||
|
@ -240,20 +240,20 @@ shared_info::heap_chunk_size ()
|
|||
/* FIXME: We should not be restricted to a fixed size heap no matter
|
||||
what the fixed size is. */
|
||||
|
||||
initial_heap_size = reg.get_int ("heap_chunk_in_mb", 0);
|
||||
if (!initial_heap_size) {
|
||||
heap_chunk = reg.get_int ("heap_chunk_in_mb", 0);
|
||||
if (!heap_chunk) {
|
||||
reg_key r1 (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE",
|
||||
CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
|
||||
CYGWIN_INFO_CYGWIN_REGISTRY_NAME, NULL);
|
||||
initial_heap_size = reg.get_int ("heap_chunk_in_mb", 384);
|
||||
heap_chunk = reg.get_int ("heap_chunk_in_mb", 384);
|
||||
}
|
||||
|
||||
if (initial_heap_size < 4)
|
||||
initial_heap_size = 4 * 1024 * 1024;
|
||||
if (heap_chunk < 4)
|
||||
heap_chunk = 4 * 1024 * 1024;
|
||||
else
|
||||
initial_heap_size <<= 20;
|
||||
debug_printf ("fixed heap size is %u", initial_heap_size);
|
||||
heap_chunk <<= 20;
|
||||
debug_printf ("fixed heap size is %u", heap_chunk);
|
||||
}
|
||||
|
||||
return initial_heap_size;
|
||||
return heap_chunk;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ public:
|
|||
|
||||
#define SHARED_INFO_CB 47112
|
||||
|
||||
#define CURR_SHARED_MAGIC 0xd9e0bc22U
|
||||
#define CURR_SHARED_MAGIC 0x359218a2U
|
||||
|
||||
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
||||
below class. The layout is checksummed to determine compatibility between
|
||||
|
@ -148,7 +148,7 @@ class shared_info
|
|||
DWORD version;
|
||||
DWORD cb;
|
||||
public:
|
||||
unsigned initial_heap_size;
|
||||
unsigned heap_chunk;
|
||||
DWORD sys_mount_table_counter;
|
||||
|
||||
tty_list tty;
|
||||
|
|
|
@ -14,12 +14,18 @@ details. */
|
|||
#include <wingdi.h>
|
||||
#include <winuser.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "pinfo.h"
|
||||
#include "perprocess.h"
|
||||
#include "cygwin_version.h"
|
||||
#include "hires.h"
|
||||
#include "security.h"
|
||||
#include "cygthread.h"
|
||||
#include "shared_info.h"
|
||||
#include "fhandler.h"
|
||||
#include "path.h"
|
||||
#include "dtable.h"
|
||||
#include "cygerrno.h"
|
||||
#include "cygheap.h"
|
||||
|
||||
#define PROTECT(x) x[sizeof (x)-1] = 0
|
||||
#define CHECK(x) if (x[sizeof (x)-1] != 0) { small_printf ("array bound exceeded %d\n", __LINE__); ExitProcess (1); }
|
||||
|
@ -58,7 +64,7 @@ strace::hello ()
|
|||
cygwin_version.api_major, cygwin_version.api_minor);
|
||||
prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date);
|
||||
prntf (1, NULL, "OS version: Windows %s", wincap.osname ());
|
||||
prntf (1, NULL, "Heap size: %u", cygwin_shared->heap_chunk_size ());
|
||||
prntf (1, NULL, "Heap size: %u", cygheap->user_heap.chunk);
|
||||
prntf (1, NULL, "**********************************************");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue