2014-07-16 Corinna Vinschen <corinna@vinschen.de>

* thread.cc (pthread::create): Handle stackaddr as upper bound address.
	Add comment.
	(pthread_attr_setstack): Store upper bound address in stackaddr.
	Explain why.
	(pthread_attr_getstack): Handle stackaddr as upper bound address.
	Add comment.
	(pthread_attr_setstackaddr): Add comment.
	(pthread_attr_getstackaddr): Add comment.
	(pthread_attr_getstacksize): Return default stacksize if stacksize has
	not been set by the application, just as on Linux.  Add comment.
	(pthread_getattr_np): Store upper bound address in stackaddr.  Explain
	why.
	* include/pthread.h: Remove outdated comment.
	(pthread_attr_getstackaddr): Mark as deprecated, as on Linux.
	(pthread_attr_setstackaddr): Ditto.

2014-07-15  Christopher Faylor  <me.cygwin2014@cgf.cx>

	* sigproc.cc (sigproc_init): Set aside more buffer space for signal
	pipes.
	(sig_send): Retry WriteFiles which fail when there is no error but
	packbytes have not been sent.
This commit is contained in:
Corinna Vinschen 2014-07-16 10:28:48 +00:00
parent 480ee6e4b2
commit 427ab31e90
5 changed files with 82 additions and 18 deletions

View File

@ -1,3 +1,28 @@
2014-07-16 Corinna Vinschen <corinna@vinschen.de>
* thread.cc (pthread::create): Handle stackaddr as upper bound address.
Add comment.
(pthread_attr_setstack): Store upper bound address in stackaddr.
Explain why.
(pthread_attr_getstack): Handle stackaddr as upper bound address.
Add comment.
(pthread_attr_setstackaddr): Add comment.
(pthread_attr_getstackaddr): Add comment.
(pthread_attr_getstacksize): Return default stacksize if stacksize has
not been set by the application, just as on Linux. Add comment.
(pthread_getattr_np): Store upper bound address in stackaddr. Explain
why.
* include/pthread.h: Remove outdated comment.
(pthread_attr_getstackaddr): Mark as deprecated, as on Linux.
(pthread_attr_setstackaddr): Ditto.
2014-07-15 Christopher Faylor <me.cygwin2014@cgf.cx>
* sigproc.cc (sigproc_init): Set aside more buffer space for signal
pipes.
(sig_send): Retry WriteFiles which fail when there is no error but
packbytes have not been sent.
2014-07-15 Christopher Faylor <me.cygwin2014@cgf.cx>
* sigproc.cc (send_sig): Don't report an error if WriteFile succeeds.

View File

@ -1,7 +1,7 @@
/* pthread.h: POSIX pthread interface
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2011, 2012, 2013 Red Hat, Inc.
2007, 2011, 2012, 2013, 2014 Red Hat, Inc.
Written by Marco Fuykschot <marco@ddi.nl>
@ -75,7 +75,8 @@ int pthread_attr_getschedparam (const pthread_attr_t *, struct sched_param *);
int pthread_attr_getschedpolicy (const pthread_attr_t *, int *);
int pthread_attr_getscope (const pthread_attr_t *, int *);
int pthread_attr_getstack (const pthread_attr_t *, void **, size_t *);
int pthread_attr_getstackaddr (const pthread_attr_t *, void **);
int pthread_attr_getstackaddr (const pthread_attr_t *, void **)
__attribute__ ((deprecated));
int pthread_attr_init (pthread_attr_t *);
int pthread_attr_setdetachstate (pthread_attr_t *, int);
int pthread_attr_setguardsize (pthread_attr_t *, size_t);
@ -85,12 +86,9 @@ int pthread_attr_setschedpolicy (pthread_attr_t *, int);
int pthread_attr_setscope (pthread_attr_t *, int);
#ifdef _POSIX_THREAD_ATTR_STACKADDR
/* These functions may be implementable via some low level trickery. For now they are
* Not supported or implemented. The prototypes are here so if someone greps the
* source they will see these comments
*/
int pthread_attr_setstack (pthread_attr_t *, void *, size_t);
int pthread_attr_setstackaddr (pthread_attr_t *, void *);
int pthread_attr_setstackaddr (pthread_attr_t *, void *)
__attribute__ ((deprecated));
#endif
#ifdef _POSIX_THREAD_ATTR_STACKSIZE

View File

@ -8,6 +8,11 @@ What changed:
- The default pthread_mutex type is now PTHREAD_MUTEX_NORMAL, rather than
PTHREAD_MUTEX_ERRORCHECK, just as on Linux.
- Align pthread_attr stack functions more closely to Linux.
- Mark pthread_attr_getstackaddr and pthread_attr_setstackaddr as deprecated,
as on Linux.
Bug Fixes
---------

View File

@ -426,7 +426,7 @@ sigproc_init ()
char char_sa_buf[1024];
PSECURITY_ATTRIBUTES sa = sec_user_nih ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
DWORD err = fhandler_pipe::create (sa, &my_readsig, &my_sendsig,
sizeof (sigpacket), "sigwait",
NSIG * sizeof (sigpacket), "sigwait",
PIPE_ADD_PID);
if (err)
{
@ -635,7 +635,19 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
}
DWORD nb;
if (!WriteFile (sendsig, leader, packsize, &nb, NULL))
BOOL res;
/* Try multiple times to send if packsize != nb since that probably
means that the pipe buffer is full. */
for (int i = 0; i < 100; i++)
{
res = WriteFile (sendsig, leader, packsize, &nb, NULL);
if (!res || packsize == nb)
break;
Sleep (10);
res = 0;
}
if (!res)
{
/* Couldn't send to the pipe. This probably means that the
process is exiting. */

View File

@ -473,9 +473,13 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
arg = threadarg;
mutex.lock ();
win32_obj_id = CygwinCreateThread (thread_init_wrapper, this, attr.stackaddr,
attr.stacksize ?: PTHREAD_DEFAULT_STACKSIZE,
attr.guardsize, 0, &thread_id);
/* 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;
PVOID stackaddr = attr.stackaddr ? ((caddr_t) attr.stackaddr - stacksize)
: NULL;
win32_obj_id = CygwinCreateThread (thread_init_wrapper, this, stackaddr,
stacksize, attr.guardsize, 0, &thread_id);
if (!win32_obj_id)
{
@ -2253,7 +2257,13 @@ pthread_attr_setstack (pthread_attr_t *attr, void *addr, size_t size)
return EINVAL;
if (size < PTHREAD_STACK_MIN)
return EINVAL;
(*attr)->stackaddr = addr;
/* The incoming address addr points to the lowest addressable byte of a
buffer of size bytes. Due to the way pthread_attr_setstackaddr is defined
on Linux, the lowest address ot the stack can't be reliably computed when
using pthread_attr_setstackaddr/pthread_attr_setstacksize. Therefore we
store the uppermost address of the stack in stackaddr. See also the
comment in pthread_attr_setstackaddr. */
(*attr)->stackaddr = (caddr_t) addr + size;
(*attr)->stacksize = size;
return 0;
}
@ -2263,7 +2273,9 @@ pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size)
{
if (!pthread_attr::is_good_object (attr))
return EINVAL;
*addr = (*attr)->stackaddr;
/* stackaddr holds the uppermost stack address. See the comment in
pthread_attr_setstack. */
*addr = (caddr_t) (*attr)->stackaddr - (*attr)->stacksize;
*size = (*attr)->stacksize;
return 0;
}
@ -2275,6 +2287,12 @@ pthread_attr_setstackaddr (pthread_attr_t *attr, void *addr)
return EINVAL;
if (addr == NULL)
return EINVAL;
/* This function is deprecated in SUSv4, but SUSv3 didn't define
if the incoming stack address is the lowest address of the memory
area defined as stack, or if it's the start address of the stack
at which it begins its growth. On Linux it's the latter which
means the uppermost stack address on x86 based systems. See comment
in pthread_attr_setstack as well. */
(*attr)->stackaddr = addr;
return 0;
}
@ -2284,6 +2302,7 @@ pthread_attr_getstackaddr (const pthread_attr_t *attr, void **addr)
{
if (!pthread_attr::is_good_object (attr))
return EINVAL;
/* See comment in pthread_attr_setstackaddr. */
*addr = (*attr)->stackaddr;
return 0;
}
@ -2304,7 +2323,10 @@ pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
{
if (!pthread_attr::is_good_object (attr))
return EINVAL;
*size = (*attr)->stacksize;
/* 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;
return 0;
}
@ -2486,10 +2508,12 @@ pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
if (NT_SUCCESS (status))
{
PTEB teb = (PTEB) tbi->TebBaseAddress;
(*attr)->stackaddr = teb->DeallocationStack ?: teb->Tib.StackLimit;
/* stack grows downwards on x86 systems */
/* stackaddr holds the uppermost stack address. See the comments
in pthread_attr_setstack and pthread_attr_setstackaddr for a
description. */
(*attr)->stackaddr = teb->Tib.StackBase;
(*attr)->stacksize = (uintptr_t) teb->Tib.StackBase
- (uintptr_t) (*attr)->stackaddr;
- (uintptr_t) (teb->DeallocationStack ?: teb->Tib.StackLimit);
}
else
{