From ce48510394663e2fbac99395030cdecdf0b61671 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 11 Feb 2012 17:37:02 +0000 Subject: [PATCH] * miscfuncs.cc (DEFAULT_STACKSIZE): Remove. (CygwinCreateThread): Simplify code by assuming that now stack-related input values are undefined. Set stack protection to PAGE_READWRITE, as is default on Windows. Add lengthy comment to explain POSIX guardpage. * thread.cc (pthread_attr::pthread_attr): Initialize stacksize as PTHREAD_DEFAULT_STACKSIZE. Initialize guardsize as PTHREAD_DEFAULT_GUARDSIZE. * thread.h (PTHREAD_DEFAULT_STACKSIZE): Define. Add comment to explain. (PTHREAD_DEFAULT_GUARDSIZE): Define. --- winsup/cygwin/ChangeLog | 13 +++++++++++++ winsup/cygwin/miscfuncs.cc | 35 ++++++++++++++--------------------- winsup/cygwin/thread.cc | 4 ++-- winsup/cygwin/thread.h | 6 ++++++ 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1b84e7cf4..fcbc8fad0 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,16 @@ +2012-02-11 Corinna Vinschen + + * miscfuncs.cc (DEFAULT_STACKSIZE): Remove. + (CygwinCreateThread): Simplify code by assuming that now stack-related + input values are undefined. Set stack protection to PAGE_READWRITE, + as is default on Windows. Add lengthy comment to explain POSIX + guardpage. + * thread.cc (pthread_attr::pthread_attr): Initialize stacksize as + PTHREAD_DEFAULT_STACKSIZE. Initialize guardsize as + PTHREAD_DEFAULT_GUARDSIZE. + * thread.h (PTHREAD_DEFAULT_STACKSIZE): Define. Add comment to explain. + (PTHREAD_DEFAULT_GUARDSIZE): Define. + 2012-02-10 Corinna Vinschen * miscfuncs.cc (DEFAULT_STACKSIZE): Set to 1 Megs. Drop comment about diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 85507da04..53ae58571 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -549,8 +549,6 @@ thread_wrapper (VOID *arg) ExitThread (0); } -#define DEFAULT_STACKSIZE (1024 * 1024) - HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg, PVOID stackaddr, ULONG stacksize, ULONG guardsize, @@ -572,30 +570,19 @@ CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg, wrapper_arg->func = thread_func; wrapper_arg->arg = thread_arg; - /* Set stacksize. */ - real_stacksize = stacksize ?: DEFAULT_STACKSIZE; - if (real_stacksize < PTHREAD_STACK_MIN) - real_stacksize = PTHREAD_STACK_MIN; if (stackaddr) { /* If the application provided the stack, just use it. */ wrapper_arg->stackaddr = (char *) stackaddr; - wrapper_arg->stackbase = (char *) stackaddr + real_stacksize; + wrapper_arg->stackbase = (char *) stackaddr + stacksize; } else { /* If not, we have to create the stack here. */ - real_stacksize = roundup2 (real_stacksize, wincap.page_size ()); - /* If no guardsize has been specified by the application, use the - system pagesize as default. */ - real_guardsize = (guardsize != (ULONG) -1) - ? guardsize : wincap.page_size (); - if (real_guardsize) - real_guardsize = roundup2 (real_guardsize, wincap.page_size ()); - /* Add the guardsize to the stacksize, but only if the stacksize and - the guardsize have been explicitely specified. */ - if (stacksize || guardsize != (ULONG) -1) - real_stacksize += real_guardsize; + real_stacksize = roundup2 (stacksize, wincap.page_size ()); + real_guardsize = roundup2 (guardsize, wincap.page_size ()); + /* Add the guardsize to the stacksize */ + real_stacksize += real_guardsize; /* Now roundup the result to the next allocation boundary. */ real_stacksize = roundup2 (real_stacksize, wincap.allocation_granularity ()); @@ -606,7 +593,7 @@ CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg, the Cygwin DLL comes to mind. */ real_stackaddr = VirtualAlloc (NULL, real_stacksize, MEM_RESERVE | MEM_TOP_DOWN, - PAGE_EXECUTE_READWRITE); + PAGE_READWRITE); if (!real_stackaddr) return NULL; /* Set up committed region. In contrast to the OS we commit 64K and @@ -615,13 +602,19 @@ CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg, + real_stacksize - wincap.allocation_granularity (); if (!VirtualAlloc (commitaddr, wincap.page_size (), MEM_COMMIT, - PAGE_EXECUTE_READWRITE | PAGE_GUARD)) + PAGE_READWRITE | PAGE_GUARD)) goto err; commitaddr += wincap.page_size (); if (!VirtualAlloc (commitaddr, wincap.allocation_granularity () - wincap.page_size (), MEM_COMMIT, - PAGE_EXECUTE_READWRITE)) + 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); diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 5425a9354..ea9eda2b1 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -1127,8 +1127,8 @@ pthread::resume () pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC), joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS), -inheritsched (PTHREAD_INHERIT_SCHED), stackaddr (NULL), stacksize (0), -guardsize ((size_t) -1) +inheritsched (PTHREAD_INHERIT_SCHED), stackaddr (NULL), +stacksize (PTHREAD_DEFAULT_STACKSIZE), guardsize (PTHREAD_DEFAULT_GUARDSIZE) { schedparam.sched_priority = 0; } diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index fd9724cbb..9adc9e1c7 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -16,6 +16,12 @@ details. */ #define WRITE_LOCK 1 #define READ_LOCK 2 +/* Default is a 1 Megs stack with a 4K guardpage. Since the pthread stacksize + does not include the guardpage size, but we don't want to waste another 64K, + subtract the default guardpage size from the stacksize. */ +#define PTHREAD_DEFAULT_STACKSIZE (1024 * 1024 - wincap.page_size ()) +#define PTHREAD_DEFAULT_GUARDSIZE (wincap.page_size ()) + #include #include #include "security.h"