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>2014-07-16 14:21:18 +0400
committerCorinna Vinschen <corinna@vinschen.de>2014-07-16 14:21:18 +0400
commit2f84de1ff5872260898773859ea2d88cf90c232e (patch)
tree86ab8e610ca632cd1a6604e31f0c6fb6e9c7b913
parentee5055296a64186b7561c7461b1797b584da7ff2 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog18
-rw-r--r--winsup/cygwin/include/pthread.h12
-rw-r--r--winsup/cygwin/thread.cc42
3 files changed, 56 insertions, 16 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index d1bac2ff0..bc71d7a79 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,21 @@
+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
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index bfedf1f75..9170d96fc 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -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
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 8fdbf3610..fc70c3752 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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
{