Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2012-02-13 17:12:37 +0400
committerCorinna Vinschen <corinna@vinschen.de>2012-02-13 17:12:37 +0400
commitd7bcd2a16f4dfad45357c57bc6334db51652215e (patch)
treef066a688df2d64de276da2b10d22960ea429d533 /winsup/cygwin/miscfuncs.cc
parente633eaec087cc723ce6af440ed8b91d44a35cf79 (diff)
* Makefile.in (clean): Remove non-existant regexp dir.
* collate.h: New header. (__collate_range_cmp): Declare. (__collate_load_error): Define. * glob.cc: Pull in latest version from FreeBSD. Simplify and reduce Cygwin-specific changes. * regex/regcomp.c: Include collate.h on Cygwin as well. (__collate_range_cmp): Move from here... * nlsfuncs.cc (__collate_range_cmp): ...to here. * miscfuncs.cc (thread_wrapper): Fix typo in comment. (CygwinCreateThread): Take dead zone of Windows stack into account. Change the way how the stack is commited and how to handle guardpages. Explain how and why. * thread.h (PTHREAD_DEFAULT_STACKSIZE): Change definition. Explain why.
Diffstat (limited to 'winsup/cygwin/miscfuncs.cc')
-rw-r--r--winsup/cygwin/miscfuncs.cc67
1 files changed, 44 insertions, 23 deletions
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc
index 53ae58571..3743ead65 100644
--- a/winsup/cygwin/miscfuncs.cc
+++ b/winsup/cygwin/miscfuncs.cc
@@ -527,7 +527,7 @@ thread_wrapper (VOID *arg)
xorl %%ebp, %%ebp # Set ebp to 0 \n\
# Make gcc 3.x happy and align the stack so that it is \n\
# 16 byte aligned right before the final call opcode. \n\
- andl $-16, %%esp # 16 bit align \n\
+ andl $-16, %%esp # 16 byte align \n\
addl $-12, %%esp # 12 bytes + 4 byte arg = 16 \n\
# Now we moved to the new stack. Save thread func address\n\
# and thread arg on new stack \n\
@@ -578,11 +578,17 @@ CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg,
}
else
{
+ char *commitaddr;
+
/* If not, we have to create the stack here. */
real_stacksize = roundup2 (stacksize, wincap.page_size ());
real_guardsize = roundup2 (guardsize, wincap.page_size ());
/* Add the guardsize to the stacksize */
real_stacksize += real_guardsize;
+ /* If we use the default Windows guardpage method, we have to take
+ the 2 pages dead zone into account. */
+ if (real_guardsize == wincap.page_size ())
+ real_stacksize += 2 * wincap.page_size ();
/* Now roundup the result to the next allocation boundary. */
real_stacksize = roundup2 (real_stacksize,
wincap.allocation_granularity ());
@@ -596,28 +602,43 @@ CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg,
PAGE_READWRITE);
if (!real_stackaddr)
return NULL;
- /* Set up committed region. In contrast to the OS we commit 64K and
- set up just a single guard page at the end. */
- char *commitaddr = (char *) real_stackaddr
- + real_stacksize
- - wincap.allocation_granularity ();
- if (!VirtualAlloc (commitaddr, wincap.page_size (), MEM_COMMIT,
- PAGE_READWRITE | PAGE_GUARD))
- goto err;
- commitaddr += wincap.page_size ();
- if (!VirtualAlloc (commitaddr, wincap.allocation_granularity ()
- - wincap.page_size (), MEM_COMMIT,
- PAGE_READWRITE))
- goto err;
- /* If the guardsize is != 0 (which is the default), set up a POSIX
- guardpage at the end of the stack. This isn't the same as the
- Windows guardpage, which is used to convert reserved stack to
- commited stack if necessary. Rather, the POSIX guardpage consists
- of one or more memory pages with NOACCESS protection. It's supposed
- to safeguard memory areas beyond the stack against stack overflow. */
- if (real_guardsize)
- VirtualAlloc (real_stackaddr, real_guardsize, MEM_COMMIT,
- PAGE_NOACCESS);
+ /* Set up committed region. Two cases: */
+ if (real_guardsize != wincap.page_size ())
+ {
+ /* If guardsize is set to something other than the page size, we
+ commit the entire stack and, if guardsize is > 0, we set up a
+ POSIX guardpage. We don't set up a Windows guardpage. */
+ if (!VirtualAlloc (real_stackaddr, real_guardsize, MEM_COMMIT,
+ PAGE_NOACCESS))
+ goto err;
+ commitaddr = (char *) real_stackaddr + real_guardsize;
+ if (!VirtualAlloc (commitaddr, real_stacksize - real_guardsize,
+ MEM_COMMIT, PAGE_READWRITE))
+ goto err;
+ }
+ else
+ {
+ /* If guardsize is exactly the page_size, we can assume that the
+ application will behave Windows conformant in terms of stack usage.
+ We can especially assume that it never allocates more than one
+ page at a time (alloca/_chkstk). Therefore, this is the default
+ case which allows a Windows compatible stack setup with a
+ reserved region, a guard page, and a commited region. We don't
+ need to set up a POSIX guardpage since Windows already handles
+ stack overflow: Trying to extend the stack into the last three
+ pages of the stack results in a SEGV.
+ We always commit 64K here, starting with the guardpage. */
+ commitaddr = (char *) real_stackaddr + real_stacksize
+ - wincap.allocation_granularity ();
+ if (!VirtualAlloc (commitaddr, wincap.page_size (), MEM_COMMIT,
+ PAGE_READWRITE | PAGE_GUARD))
+ goto err;
+ commitaddr += wincap.page_size ();
+ if (!VirtualAlloc (commitaddr, wincap.allocation_granularity ()
+ - wincap.page_size (), MEM_COMMIT,
+ PAGE_READWRITE))
+ goto err;
+ }
wrapper_arg->stackaddr = (char *) real_stackaddr;
wrapper_arg->stackbase = (char *) real_stackaddr + real_stacksize;
wrapper_arg->commitaddr = commitaddr;