* 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:
Christopher Faylor 2002-10-22 16:18:55 +00:00
parent 5ec14fe40a
commit 1cc651ecaf
11 changed files with 142 additions and 89 deletions

View File

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

View File

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

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

@ -47,28 +47,29 @@ shared_name (const char *str, int num)
#define page_const (65535)
#define pround(n) (((size_t) (n) + page_const) & ~page_const)
static char *offsets[] =
{
(char *) cygwin_shared_address,
(char *) cygwin_shared_address
+ pround (sizeof (shared_info)),
(char *) cygwin_shared_address
+ pround (sizeof (shared_info))
+ pround (sizeof (mount_info)),
(char *) cygwin_shared_address
+ pround (sizeof (shared_info))
+ pround (sizeof (mount_info))
+ pround (sizeof (console_state)),
(char *) cygwin_shared_address
+ pround (sizeof (shared_info))
+ 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;
static char *offsets[] =
{
(char *) cygwin_shared_address,
(char *) cygwin_shared_address
+ pround (sizeof (shared_info)),
(char *) cygwin_shared_address
+ pround (sizeof (shared_info))
+ pround (sizeof (mount_info)),
(char *) cygwin_shared_address
+ pround (sizeof (shared_info))
+ pround (sizeof (mount_info))
+ pround (sizeof (console_state)),
(char *) cygwin_shared_address
+ pround (sizeof (shared_info))
+ pround (sizeof (mount_info))
+ pround (sizeof (console_state))
+ pround (sizeof (_pinfo))
};
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;
}

View File

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

View File

@ -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, "**********************************************");
}
}