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>2011-05-15 22:49:40 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-05-15 22:49:40 +0400
commitcdb4231369f4c06795e170f9cb003d8de1581f5b (patch)
treedd008237ecd92aa1101affbc9577809aa49b8dd5
parent2922c6c4aaa754fee3fcaecddd618ec9dff84cc5 (diff)
* cygwin.din (pthread_attr_getguardsize): Export.
(pthread_attr_setguardsize): Export. (pthread_attr_setstack): Export. (pthread_attr_setstackaddr): Export. * init.cc (dll_entry): Remove wow64_test_stack_marker. Check for unusual stack address by testing stack addresses from current TEB. Check validity of _my_tls by testing if it's within the stack as given in current TEB. * miscfuncs.cc (struct thread_wrapper_arg): New structure used to push all required information to thread_wrapper function. (thread_wrapper): Wrapper function for actual thread function. If an application stack has been given, change %ebp and %esp so that the thread function runs on that stack. If the thread has been created by CygwinCreateThread, set up the POSIX guard pages if necessary. (CygwinCreateThread): New function. * miscfuncs.h (CygwinCreateThread): Declare. * ntdll.h (struct _TEB): Define all members up to Peb. * posix.sgml (std-susv4): Move pthread_attr_getguardsize, pthread_attr_setguardsize and pthread_attr_setstack here. (std-deprec): Add pthread_attr_setstackaddr. * sysconf.cc (sca): Set _SC_THREAD_ATTR_STACKADDR to _POSIX_THREAD_ATTR_STACKADDR. * thread.cc (pthread::precreate): Copy pthread_attr stackaddr and guardsize members. (pthread::create): Call CygwinCreateThread. (pthread_attr::pthread_attr): Initialize guardsize. (pthread_attr_setstack): New function. (pthread_attr_setstackaddr): New function. (pthread_attr_setguardsize): New function. (pthread_attr_getguardsize): New function. (pthread_getattr_np): Copy attr.guardsize. * thread.h (pthread_attr): Add member guardsize. * include/pthread.h (pthread_attr_getguardsize): Declare. (pthread_attr_setguardsize): Declare. * include/cygwin/version.h: Bump API minor number.
-rw-r--r--winsup/cygwin/ChangeLog38
-rw-r--r--winsup/cygwin/cygwin.din4
-rw-r--r--winsup/cygwin/include/cygwin/version.h4
-rw-r--r--winsup/cygwin/include/pthread.h2
-rw-r--r--winsup/cygwin/init.cc14
-rw-r--r--winsup/cygwin/miscfuncs.cc142
-rw-r--r--winsup/cygwin/miscfuncs.h9
-rw-r--r--winsup/cygwin/ntdll.h12
-rw-r--r--winsup/cygwin/posix.sgml7
-rw-r--r--winsup/cygwin/sysconf.cc4
-rw-r--r--winsup/cygwin/thread.cc61
-rw-r--r--winsup/cygwin/thread.h1
12 files changed, 274 insertions, 24 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0733a86a7..415be6df3 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,41 @@
+2011-05-15 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygwin.din (pthread_attr_getguardsize): Export.
+ (pthread_attr_setguardsize): Export.
+ (pthread_attr_setstack): Export.
+ (pthread_attr_setstackaddr): Export.
+ * init.cc (dll_entry): Remove wow64_test_stack_marker. Check for
+ unusual stack address by testing stack addresses from current TEB.
+ Check validity of _my_tls by testing if it's within the stack as
+ given in current TEB.
+ * miscfuncs.cc (struct thread_wrapper_arg): New structure used to
+ push all required information to thread_wrapper function.
+ (thread_wrapper): Wrapper function for actual thread function.
+ If an application stack has been given, change %ebp and %esp so that
+ the thread function runs on that stack. If the thread has been created
+ by CygwinCreateThread, set up the POSIX guard pages if necessary.
+ (CygwinCreateThread): New function.
+ * miscfuncs.h (CygwinCreateThread): Declare.
+ * ntdll.h (struct _TEB): Define all members up to Peb.
+ * posix.sgml (std-susv4): Move pthread_attr_getguardsize,
+ pthread_attr_setguardsize and pthread_attr_setstack here.
+ (std-deprec): Add pthread_attr_setstackaddr.
+ * sysconf.cc (sca): Set _SC_THREAD_ATTR_STACKADDR to
+ _POSIX_THREAD_ATTR_STACKADDR.
+ * thread.cc (pthread::precreate): Copy pthread_attr stackaddr and
+ guardsize members.
+ (pthread::create): Call CygwinCreateThread.
+ (pthread_attr::pthread_attr): Initialize guardsize.
+ (pthread_attr_setstack): New function.
+ (pthread_attr_setstackaddr): New function.
+ (pthread_attr_setguardsize): New function.
+ (pthread_attr_getguardsize): New function.
+ (pthread_getattr_np): Copy attr.guardsize.
+ * thread.h (pthread_attr): Add member guardsize.
+ * include/pthread.h (pthread_attr_getguardsize): Declare.
+ (pthread_attr_setguardsize): Declare.
+ * include/cygwin/version.h: Bump API minor number.
+
2011-05-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler_process.cc (struct heap_info::heap): Convert base to
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index 2eafd2c8c..12c3f3d57 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -1174,6 +1174,7 @@ psignal SIGFE
pthread_atfork SIGFE
pthread_attr_destroy SIGFE
pthread_attr_getdetachstate SIGFE
+pthread_attr_getguardsize SIGFE
pthread_attr_getinheritsched SIGFE
pthread_attr_getschedparam SIGFE
pthread_attr_getschedpolicy SIGFE
@@ -1183,10 +1184,13 @@ pthread_attr_getstackaddr SIGFE
pthread_attr_getstacksize SIGFE
pthread_attr_init SIGFE
pthread_attr_setdetachstate SIGFE
+pthread_attr_setguardsize SIGFE
pthread_attr_setinheritsched SIGFE
pthread_attr_setschedparam SIGFE
pthread_attr_setschedpolicy SIGFE
pthread_attr_setscope SIGFE
+pthread_attr_setstack SIGFE
+pthread_attr_setstackaddr SIGFE
pthread_attr_setstacksize SIGFE
pthread_cancel SIGFE
_pthread_cleanup_pop SIGFE
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index cf03080df..ea66d4097 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -410,12 +410,14 @@ details. */
242: Export psiginfo, psignal, sys_siglist.
243: Export sysinfo.
244: Export clock_settime.
+ 245: Export pthread_attr_getguardsize, pthread_attr_setguardsize,
+ pthread_attr_setstack, pthread_attr_setstackaddr.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 244
+#define CYGWIN_VERSION_API_MINOR 245
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index c76cd670b..e963eba54 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -72,6 +72,7 @@ extern "C"
/* Attributes */
int pthread_attr_destroy (pthread_attr_t *);
int pthread_attr_getdetachstate (const pthread_attr_t *, int *);
+int pthread_attr_getguardsize (const pthread_attr_t *, size_t *);
int pthread_attr_getinheritsched (const pthread_attr_t *, int *);
int pthread_attr_getschedparam (const pthread_attr_t *, struct sched_param *);
int pthread_attr_getschedpolicy (const pthread_attr_t *, int *);
@@ -80,6 +81,7 @@ int pthread_attr_getstack (const pthread_attr_t *, void **, size_t *);
int pthread_attr_getstackaddr (const pthread_attr_t *, void **);
int pthread_attr_init (pthread_attr_t *);
int pthread_attr_setdetachstate (pthread_attr_t *, int);
+int pthread_attr_setguardsize (pthread_attr_t *, size_t);
int pthread_attr_setinheritsched (pthread_attr_t *, int);
int pthread_attr_setschedparam (pthread_attr_t *, const struct sched_param *);
int pthread_attr_setschedpolicy (pthread_attr_t *, int);
diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc
index fab71ba27..5404ed15a 100644
--- a/winsup/cygwin/init.cc
+++ b/winsup/cygwin/init.cc
@@ -1,7 +1,7 @@
/* init.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009 Red Hat, Inc.
+ 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin.
@@ -115,7 +115,7 @@ extern void __stdcall dll_crt0_0 ();
extern "C" BOOL WINAPI
dll_entry (HANDLE h, DWORD reason, void *static_load)
{
- BOOL wow64_test_stack_marker;
+ PNT_TIB tib;
switch (reason)
{
@@ -131,9 +131,10 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
the auto load address of DLLs?
Check if we're running in WOW64 on a 64 bit machine *and* are
spawned by a genuine 64 bit process. If so, respawn. */
+ tib = &NtCurrentTeb ()->Tib;
if (wincap.is_wow64 ()
- && &wow64_test_stack_marker >= (PBOOL) 0x400000
- && &wow64_test_stack_marker <= (PBOOL) 0x10000000)
+ && tib->StackLimit >= (PBOOL) 0x400000
+ && tib->StackBase <= (PBOOL) 0x10000000)
respawn_wow64_process ();
dll_crt0_0 ();
@@ -149,7 +150,10 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
munge_threadfunc ();
break;
case DLL_THREAD_DETACH:
- if (dll_finished_loading && (void *) &_my_tls > (void *) &wow64_test_stack_marker
+ tib = &NtCurrentTeb ()->Tib;
+ if (dll_finished_loading
+ && (PVOID) &_my_tls >= tib->StackLimit
+ && (PVOID) &_my_tls < tib->StackBase
&& _my_tls.isinitialized ())
_my_tls.remove (0);
break;
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc
index 706347240..0e2945125 100644
--- a/winsup/cygwin/miscfuncs.cc
+++ b/winsup/cygwin/miscfuncs.cc
@@ -1,7 +1,7 @@
/* miscfuncs.cc: misc funcs that don't belong anywhere else
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2011 Red Hat, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin.
@@ -15,12 +15,17 @@ details. */
#include <assert.h>
#include <alloca.h>
#include <limits.h>
+#include <sys/param.h>
#include <wchar.h>
#include <wingdi.h>
#include <winuser.h>
#include <winnls.h>
#include "cygtls.h"
#include "ntdll.h"
+#include "path.h"
+#include "fhandler.h"
+#include "dtable.h"
+#include "cygheap.h"
long tls_ix = -1;
@@ -376,3 +381,138 @@ slashify (const char *src, char *dst, bool trailing_slash_p)
*dst++ = '/';
*dst++ = 0;
}
+
+/* CygwinCreateThread.
+
+ Replacement function for CreateThread. What we do here is to remove
+ parameters we don't use and instead to add parameters we need to make
+ the function pthreads compatible. */
+
+struct thread_wrapper_arg
+{
+ LPTHREAD_START_ROUTINE func;
+ PVOID arg;
+ PVOID stackaddr;
+ ULONG stacksize;
+ ULONG guardsize;
+};
+
+DWORD WINAPI
+thread_wrapper (VOID *arg)
+{
+ if (!arg)
+ return ERROR_INVALID_PARAMETER;
+
+ thread_wrapper_arg wrapper_arg = *(thread_wrapper_arg *) arg;
+ cfree (arg);
+
+ if (wrapper_arg.stackaddr)
+ {
+ /* If the application provided the stack, we must make sure that
+ it's actually used by the thread function. So what we do here is
+ to compute the stackbase of the application-provided stack and
+ change the stack pointer accordingly.
+
+ NOTE: _my_tls is on the stack created by CreateThread! It's
+ unlikely the tls structure will ever exceed 64K, but if
+ so, we have to raise the size of the stack in the call
+ to CreateThread, too. */
+ wrapper_arg.stackaddr = (PVOID) ((PBYTE) wrapper_arg.stackaddr
+ + wrapper_arg.stacksize
+ - sizeof (PVOID));
+ __asm__ ("\n\
+ movl %[WRAPPER_ARG], %%ebx \n\
+ movl (%%ebx), %%eax \n\
+ movl 4(%%ebx), %%ecx \n\
+ movl 8(%%ebx), %%edx \n\
+ xorl %%ebp, %%ebp \n\
+ movl %%edx, %%esp \n\
+ pushl %%ecx \n\
+ pushl %%eax \n\
+ jmp *%%eax \n" : : [WRAPPER_ARG] "r" (&wrapper_arg));
+
+ }
+ if (wrapper_arg.guardsize)
+ {
+ /* Set up POSIX guard pages. Note that this is not the same as the
+ PAGE_GUARD protection. Rather, the POSIX guard pages are a
+ PAGE_NOACCESS protected area which is supposed to guard against
+ stack overflow and to trigger a SIGSEGV if that happens. */
+ PNT_TIB tib = &NtCurrentTeb ()->Tib;
+ wrapper_arg.stackaddr = (PVOID) ((PBYTE) tib->StackBase
+ - wrapper_arg.stacksize);
+ if (!VirtualAlloc (wrapper_arg.stackaddr, wrapper_arg.guardsize,
+ MEM_COMMIT, PAGE_NOACCESS))
+ system_printf ("VirtualAlloc, %E");
+ }
+ __asm__ ("\n\
+ movl %[WRAPPER_ARG], %%ebx \n\
+ movl (%%ebx), %%eax \n\
+ movl 4(%%ebx), %%ecx \n\
+ pushl %%ecx \n\
+ pushl %%eax \n\
+ jmp *%%eax \n" : : [WRAPPER_ARG] "r" (&wrapper_arg));
+ /* Never reached. */
+ return ERROR_INVALID_FUNCTION;
+}
+
+/* FIXME: This should be settable via setrlimit (RLIMIT_STACK). */
+#define DEFAULT_STACKSIZE (512 * 1024)
+
+HANDLE WINAPI
+CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg,
+ PVOID stackaddr, ULONG stacksize, ULONG guardsize,
+ DWORD creation_flags, LPDWORD thread_id)
+{
+ ULONG real_stacksize = 0;
+ ULONG real_guardsize = 0;
+ thread_wrapper_arg *wrapper_arg;
+
+ wrapper_arg = (thread_wrapper_arg *) ccalloc (HEAP_STR, 1,
+ sizeof *wrapper_arg);
+ if (!wrapper_arg)
+ {
+ SetLastError (ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+ 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)
+ {
+ wrapper_arg->stackaddr = stackaddr;
+ wrapper_arg->stacksize = real_stacksize;
+ real_stacksize = PTHREAD_STACK_MIN;
+ }
+ 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 != 0xffffffff)
+ ? guardsize : wincap.page_size ();
+ if (real_guardsize)
+ real_guardsize = roundup2 (real_guardsize, wincap.page_size ());
+ /* If the default stacksize is used and guardsize has not been specified,
+ don't add a guard page to the size. */
+ if (stacksize && guardsize != 0xffffffff)
+ real_stacksize += real_guardsize;
+ /* Now roundup the result to the next allocation boundary. */
+ real_stacksize = roundup2 (real_stacksize,
+ wincap.allocation_granularity ());
+
+ wrapper_arg->stacksize = real_stacksize;
+ wrapper_arg->guardsize = real_guardsize;
+ }
+ /* Use the STACK_SIZE_PARAM_IS_A_RESERVATION parameter to make sure the
+ stack size is exactly the size we want. */
+ return CreateThread (&sec_none_nih, real_stacksize, thread_wrapper,
+ wrapper_arg,
+ creation_flags | STACK_SIZE_PARAM_IS_A_RESERVATION,
+ thread_id);
+}
diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h
index 1dcb924db..6be70e343 100644
--- a/winsup/cygwin/miscfuncs.h
+++ b/winsup/cygwin/miscfuncs.h
@@ -1,7 +1,7 @@
/* miscfuncs.h: main Cygwin header file.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Red Hat, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin.
@@ -38,4 +38,11 @@ int __stdcall check_invalid_virtual_addr (const void *s, unsigned sz) __attribut
ssize_t check_iovec (const struct iovec *, int, bool) __attribute__ ((regparm(3)));
#define check_iovec_for_read(a, b) check_iovec ((a), (b), false)
#define check_iovec_for_write(a, b) check_iovec ((a), (b), true)
+
+extern "C" HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func,
+ PVOID thread_arg, PVOID stackaddr,
+ ULONG stacksize, ULONG guardsize,
+ DWORD creation_flags,
+ LPDWORD thread_id);
+
#endif /*_MISCFUNCS_H*/
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index cb4e6d962..9c5597ec1 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -622,11 +622,15 @@ typedef struct _PEB
ULONG SessionId;
} PEB, *PPEB;
-/* Simplifed definition, just to get the PEB pointer. */
+/* Simplified definition, just to get the TIB and the PEB pointer. */
typedef struct _TEB
{
- PVOID dummy[12];
- PPEB Peb;
+ NT_TIB Tib;
+ PVOID EnvironmentPointer;
+ CLIENT_ID ClientId;
+ PVOID ActiveRpcHandle;
+ PVOID ThreadLocalStoragePointer;
+ PPEB Peb;
/* A lot more follows... */
} TEB, *PTEB;
@@ -1111,9 +1115,7 @@ extern "C"
ULONG, ULONG *);
NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
PVOID, ULONG, PULONG);
-
NTSTATUS WINAPI NtQuerySystemTime (PLARGE_INTEGER);
-
NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR, ULONG, PULONG);
NTSTATUS NTAPI NtQuerySymbolicLinkObject (HANDLE, PUNICODE_STRING, PULONG);
diff --git a/winsup/cygwin/posix.sgml b/winsup/cygwin/posix.sgml
index 235ee2f94..a576b353f 100644
--- a/winsup/cygwin/posix.sgml
+++ b/winsup/cygwin/posix.sgml
@@ -532,6 +532,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
pthread_atfork
pthread_attr_destroy
pthread_attr_getdetachstate
+ pthread_attr_getguardsize
pthread_attr_getinheritsched
pthread_attr_getschedparam
pthread_attr_getschedpolicy
@@ -540,10 +541,12 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
pthread_attr_getstacksize
pthread_attr_init
pthread_attr_setdetachstate
+ pthread_attr_setguardsize
pthread_attr_setinheritsched
pthread_attr_setschedparam
pthread_attr_setschedpolicy
pthread_attr_setscope
+ pthread_attr_setstack
pthread_attr_setstacksize
pthread_cancel
pthread_cond_broadcast
@@ -1237,6 +1240,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
mktemp (SUSv3)
on_exit (SunOS)
pthread_attr_getstackaddr (SUSv3)
+ pthread_attr_setstackaddr (SUSv3)
pthread_continue (XPG2)
pthread_getsequence_np (Tru64)
pthread_suspend (XPG2)
@@ -1379,9 +1383,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
posix_trace[...]
posix_typed_[...]
powl
- pthread_attr_getguardsize
- pthread_attr_setguardsize
- pthread_attr_setstack
pthread_barrier[...]
pthread_condattr_getclock
pthread_condattr_setclock
diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc
index de84dbc3e..73c44fe36 100644
--- a/winsup/cygwin/sysconf.cc
+++ b/winsup/cygwin/sysconf.cc
@@ -140,8 +140,8 @@ static struct
{cons, {c:-1L}}, /* 40, _SC_THREAD_THREADS_MAX */
{cons, {c:TTY_NAME_MAX}}, /* 41, _SC_TTY_NAME_MAX */
{cons, {c:_POSIX_THREADS}}, /* 42, _SC_THREADS */
- {cons, {c:-1L}}, /* 43, _SC_THREAD_ATTR_STACKADDR */
- {cons, {c:_POSIX_THREAD_ATTR_STACKSIZE}}, /* 44, _SC_THREAD_ATTR_STACKSIZE */
+ {cons, {c:_POSIX_THREAD_ATTR_STACKADDR}},/* 43, _SC_THREAD_ATTR_STACKADDR */
+ {cons, {c:_POSIX_THREAD_ATTR_STACKSIZE}},/* 44, _SC_THREAD_ATTR_STACKSIZE */
{cons, {c:_POSIX_THREAD_PRIORITY_SCHEDULING}}, /* 45, _SC_THREAD_PRIORITY_SCHEDULING */
{cons, {c:-1L}}, /* 46, _SC_THREAD_PRIO_INHERIT */
{cons, {c:-1L}}, /* 47, _SC_THREAD_PRIO_PROTECT */
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 60a6d3a77..b53fc7f70 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -23,9 +23,6 @@ details. */
R.Collins, April 2001. */
-#ifdef HAVE_CONFIG_H
-#endif
-
#include "winsup.h"
#include "miscfuncs.h"
#include "path.h"
@@ -38,6 +35,7 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
+#include "miscfuncs.h"
extern "C" void __fp_lock_all ();
extern "C" void __fp_unlock_all ();
@@ -425,7 +423,9 @@ pthread::precreate (pthread_attr *newattr)
attr.joinable = newattr->joinable;
attr.contentionscope = newattr->contentionscope;
attr.inheritsched = newattr->inheritsched;
+ attr.stackaddr = newattr->stackaddr;
attr.stacksize = newattr->stacksize;
+ attr.guardsize = newattr->guardsize;
}
if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
@@ -455,8 +455,9 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
arg = threadarg;
mutex.lock ();
- win32_obj_id = ::CreateThread (&sec_none_nih, attr.stacksize,
- thread_init_wrapper, this, 0, &thread_id);
+ win32_obj_id = CygwinCreateThread (thread_init_wrapper, this,
+ attr.stackaddr, attr.stacksize,
+ attr.guardsize, 0, &thread_id);
if (!win32_obj_id)
{
@@ -1087,7 +1088,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)
+inheritsched (PTHREAD_INHERIT_SCHED), stackaddr (NULL), stacksize (0),
+guardsize (0xffffffff)
{
schedparam.sched_priority = 0;
}
@@ -2240,6 +2242,20 @@ pthread_attr_setscope (pthread_attr_t *attr, int contentionscope)
}
extern "C" int
+pthread_attr_setstack (pthread_attr_t *attr, void *addr, size_t size)
+{
+ if (!pthread_attr::is_good_object (attr))
+ return EINVAL;
+ if (addr == NULL)
+ return EINVAL;
+ if (size < PTHREAD_STACK_MIN)
+ return EINVAL;
+ (*attr)->stackaddr = addr;
+ (*attr)->stacksize = size;
+ return 0;
+}
+
+extern "C" int
pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size)
{
if (!pthread_attr::is_good_object (attr))
@@ -2251,6 +2267,17 @@ pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size)
}
extern "C" int
+pthread_attr_setstackaddr (pthread_attr_t *attr, void *addr)
+{
+ if (!pthread_attr::is_good_object (attr))
+ return EINVAL;
+ if (addr == NULL)
+ return EINVAL;
+ (*attr)->stackaddr = addr;
+ return 0;
+}
+
+extern "C" int
pthread_attr_getstackaddr (const pthread_attr_t *attr, void **addr)
{
if (!pthread_attr::is_good_object (attr))
@@ -2282,6 +2309,27 @@ pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
}
extern "C" int
+pthread_attr_setguardsize (pthread_attr_t *attr, size_t size)
+{
+ if (!pthread_attr::is_good_object (attr))
+ return EINVAL;
+ /* We don't support a guardsize of more than 1 Meg. */
+ if (size > 1024 * 1024)
+ return EINVAL;
+ (*attr)->guardsize = size;
+ return 0;
+}
+
+extern "C" int
+pthread_attr_getguardsize (const pthread_attr_t *attr, size_t *size)
+{
+ if (!pthread_attr::is_good_object (attr))
+ return EINVAL;
+ *size = (*attr)->guardsize;
+ return 0;
+}
+
+extern "C" int
pthread_attr_destroy (pthread_attr_t *attr)
{
if (!pthread_attr::is_good_object (attr))
@@ -2429,6 +2477,7 @@ pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
(*attr)->contentionscope = thread->attr.contentionscope;
(*attr)->inheritsched = thread->attr.inheritsched;
(*attr)->schedparam = thread->attr.schedparam;
+ (*attr)->guardsize = thread->attr.guardsize;
tbi = (PTHREAD_BASIC_INFORMATION) malloc (sizeof_tbi);
ret = NtQueryInformationThread (thread->win32_obj_id, ThreadBasicInformation,
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index b1969ed81..d8e4319a4 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -252,6 +252,7 @@ public:
struct sched_param schedparam;
void *stackaddr;
size_t stacksize;
+ size_t guardsize;
pthread_attr ();
~pthread_attr ();