Implement correct RLIMIT_STACK handling

* miscfuncs.cc (struct pthread_wrapper_arg): Add member guardsize.
        (pthread_wrapper): Set thread stack guarantee according to guardsize.
        Tweak assembler code so that $rax/$eax is not required by GCC to
        prepare the wrapper_arg value.
        (CygwinCreateThread): Fix deadzone handling.  Drop setting a "POSIX"
        guardpage (aka page w/ PAGE_NOACCESS).  Always use Windows guard
        pages instead.  On post-XP systems (providing SetThreadStackGuarantee)
        always set up stack Windows like with reserved/commited areas and
        movable guard pages.  Only on XP set up stack fully commited if the
        guardpage size is not the default system guardpage size.
        Fill out pthread_wrapper_arg::guardsize.  Improve comments.
        * resource.cc: Implement RSTACK_LIMIT Linux-like.
        (DEFAULT_STACKSIZE): New macro.
        (DEFAULT_STACKGUARD): Ditto.
        (rlimit_stack_guard): New muto.
        (rlimit_stack): New global variable holding current RSTACK_LIMIT values.
        (__set_rlimit_stack): Set rlimit_stack under lock.
        (__get_rlimit_stack): Initialize rlimit_stack from executable header
        and return rlimit_stack values under lock.
        (get_rlimit_stack): Filtering function to return useful default
        stacksize from rlimit_stack.rlim_cur value.
        (getrlimit): Call __get_rlimit_stack in RLIMIT_STACK case.
        (setrlimit): Call __set_rlimit_stack in RLIMIT_STACK case.
        * thread.cc (pthread::create): Fetch default stacksize calling
        get_rlimit_stack.
        (pthread_attr::pthread_attr): Fetch default guardsize calling
        wincap.def_guard_page_size.
        (pthread_attr_getstacksize): Fetch default stacksize calling
        get_rlimit_stack.
        * thread.h (PTHREAD_DEFAULT_STACKSIZE): Remove.
        (PTHREAD_DEFAULT_GUARDSIZE): Remove.
        (get_rlimit_stack): Declare.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen
2015-07-05 15:51:37 +02:00
parent e426213a88
commit a54bc198b1
7 changed files with 172 additions and 71 deletions

View File

@ -475,7 +475,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
mutex.lock ();
/* stackaddr holds the uppermost stack address. See the comments in
pthread_attr_setstack and pthread_attr_setstackaddr for a description. */
ULONG stacksize = attr.stacksize ?: PTHREAD_DEFAULT_STACKSIZE;
ULONG stacksize = attr.stacksize ?: get_rlimit_stack ();
PVOID stackaddr = attr.stackaddr ? ((caddr_t) attr.stackaddr - stacksize)
: NULL;
win32_obj_id = CygwinCreateThread (thread_init_wrapper, this, stackaddr,
@ -1093,7 +1093,7 @@ 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 (PTHREAD_DEFAULT_GUARDSIZE)
guardsize (wincap.def_guard_page_size ())
{
schedparam.sched_priority = 0;
}
@ -2330,7 +2330,7 @@ pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
/* If the stacksize has not been set by the application, return the
default stacksize. Note that this is different from what
pthread_attr_getstack returns. */
*size = (*attr)->stacksize ?: PTHREAD_DEFAULT_STACKSIZE;
*size = (*attr)->stacksize ?: get_rlimit_stack ();
return 0;
}