This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] pthread_getattr_np (take 2)


On Tue, Mar 20, 2001 at 04:19:52PM +0100, Jakub Jelinek wrote:
> Hi!
> 
> As pointed by Hui Huang, __stackaddr is stack top on machines where stack
> grows down, so pthread_getattr_np should match that.
> I'll try to write a testcase as soon.

Here is a new patch (with cast of descr->p_guardaddr) including a testcase
and a bugfix for pthread_attr_setstack, which was checking e.g. on ia32 if
stackaddr & 0xffffffdf is non-zero and thus usually failed.

2001-03-21  Jakub Jelinek  <jakub@redhat.com>

	* attr.c (__pthread_attr_setstack): Fix alignment check.
	(pthread_getattr_np): __stackaddr is top of stack, not bottom.
	* Makefile (tests): Add ex17 test.
	* Examples/ex17.c: New test.

--- libc/linuxthreads/attr.c.jj	Tue Mar 20 13:36:32 2001
+++ libc/linuxthreads/attr.c	Wed Mar 21 19:08:24 2001
@@ -225,7 +225,7 @@ int __pthread_attr_setstack (pthread_att
   int err;
 
   if ((((uintptr_t) stackaddr)
-       & ~__alignof__ (struct _pthread_descr_struct)) != 0)
+       & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0)
     err = EINVAL;
   else
     err = __pthread_attr_setstacksize (attr, stacksize);
@@ -263,7 +263,6 @@ int pthread_getattr_np (pthread_t thread
 {
   pthread_handle handle = thread_handle (thread);
   pthread_descr descr;
-  char *guardaddr;
 
   if (handle == NULL)
     return ENOENT;
@@ -282,21 +281,24 @@ int pthread_getattr_np (pthread_t thread
 			(struct sched_param *) &attr->__schedparam) != 0)
     return errno;
 
-  guardaddr = descr->p_guardaddr;
   attr->__inheritsched = descr->p_inheritsched;
   attr->__scope = PTHREAD_SCOPE_SYSTEM;
-  attr->__stacksize = (char *)(descr + 1) - guardaddr - descr->p_guardsize;
+  attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr
+		      - descr->p_guardsize;
   attr->__guardsize = descr->p_guardsize;
   attr->__stackaddr_set = descr->p_userstack;
 #ifdef NEED_SEPARATE_REGISTER_STACK
-  guardaddr -= attr->__stacksize;
   attr->__stacksize *= 2;
   /* XXX This is awkward.  The guard pages are in the middle of the
      two stacks.  We must count the guard size in the stack size since
      otherwise the range of the stack area cannot be computed.  */
   attr->__stacksize += attr->__guardsize;
 #endif
-  attr->__stackaddr = guardaddr;
+#ifndef _STACK_GROWS_UP
+  attr->__stackaddr = (char *)(descr + 1);
+#else
+#error __stackaddr not handled
+#endif
 
   return 0;
 }
--- libc/linuxthreads/Makefile.jj	Wed Mar 21 15:44:51 2001
+++ libc/linuxthreads/Makefile	Wed Mar 21 19:20:23 2001
@@ -55,7 +55,7 @@ endif
 
 librt-tests = ex10 ex11
 tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \
-	tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14 ex15 ex16
+	tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14 ex15 ex16 ex17
 
 ifeq (yes,$(build-shared))
 tests-nodelete-yes = unload
--- libc/linuxthreads/Examples/ex17.c.jj	Tue Mar 20 13:03:54 2001
+++ libc/linuxthreads/Examples/ex17.c	Wed Mar 21 19:24:27 2001
@@ -0,0 +1,95 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/mman.h>
+
+static void *
+test_thread (void *v_param)
+{
+  return NULL;
+}
+
+#define STACKSIZE 0x100000
+
+int
+main (void)
+{
+  pthread_t thread;
+  pthread_attr_t attr;
+  int status;
+  void *stack, *stack2;
+  size_t stacksize;
+
+  pthread_attr_init (&attr);
+  stack = mmap (NULL, STACKSIZE,
+		PROT_READ | PROT_WRITE | PROT_EXEC,
+		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+  if (stack == (void *)-1)
+    {
+      perror ("mmap failed");
+      return 1;
+    }
+
+  status = pthread_attr_setstack (&attr, stack, STACKSIZE);
+  if (status != 0)
+    {
+      printf ("pthread_attr_setstack failed: %s\n", strerror (status));
+      return 1;
+    }
+
+  status = pthread_attr_getstack (&attr, &stack2, &stacksize);
+  if (status != 0)
+    {
+      printf ("pthread_attr_getstack failed: %s\n", strerror (status));
+      return 1;
+    }
+
+  if (stack2 != stack || stacksize != STACKSIZE)
+    {
+      printf ("first pthread_attr_getstack returned different stack (%p,%x)\n"
+	      "than was set by setstack (%p,%x)\n",
+	      stack2, stacksize, stack, STACKSIZE);
+      return 2;
+    }
+
+  status = pthread_create (&thread, &attr, test_thread, NULL);
+  if (status != 0)
+    {
+      printf ("pthread_create failed: %s\n", strerror (status));
+      return 1;
+    }
+
+  status = pthread_getattr_np (thread, &attr);
+  if (status != 0)
+    {
+      printf ("pthread_getattr_np failed: %s\n", strerror (status));
+      return 1;
+    }
+
+  status = pthread_attr_getstack (&attr, &stack2, &stacksize);
+  if (status != 0)
+    {
+      printf ("pthread_attr_getstack failed: %s\n", strerror (status));
+      return 1;
+    }
+
+  if (stack2 != stack || stacksize != STACKSIZE)
+    {
+      printf ("second pthread_attr_getstack returned different stack (%p,%x)\n"
+	      "than was set by setstack (%p,%x)\n",
+	      stack2, stacksize, stack, STACKSIZE);
+      return 3;
+    }
+
+  /* pthread_detach (thread); */
+  if (pthread_join (thread, NULL) != 0)
+    {
+      printf ("join failed\n");
+      return 1;
+    }
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]