* 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.
This commit is contained in:
parent
2922c6c4aa
commit
cdb4231369
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -2239,6 +2241,20 @@ pthread_attr_setscope (pthread_attr_t *attr, int contentionscope)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -2250,6 +2266,17 @@ pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -2281,6 +2308,27 @@ pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
|
|
@ -252,6 +252,7 @@ public:
|
|||
struct sched_param schedparam;
|
||||
void *stackaddr;
|
||||
size_t stacksize;
|
||||
size_t guardsize;
|
||||
|
||||
pthread_attr ();
|
||||
~pthread_attr ();
|
||||
|
|
Loading…
Reference in New Issue