public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] NPTL proposed large page fix for pthread_create.
@ 2005-12-05 22:12 Steven Munroe
  2005-12-13  6:34 ` Ulrich Drepper
  0 siblings, 1 reply; 2+ messages in thread
From: Steven Munroe @ 2005-12-05 22:12 UTC (permalink / raw)
  To: libc-hacker, bmark, Roland McGrath

[-- Attachment #1: Type: text/plain, Size: 409 bytes --]

This patch fixes the problem on systems that support multiple page
sizes, but we don't want to change the PTHREAD_STACK_MIN const that is
still valid for the smaller page size and the ATTR_FLAG_STACKADDR case.
For the case where the runtime allocates the stack we need to make sure
the 2 page minimum is meet.  Where the PTHREAD_STACK_MIN is less than
the 2 page minimum, bump the allocation up to 2 pages.



[-- Attachment #2: ppc-64kpage-20051128.txt --]
[-- Type: text/plain, Size: 4703 bytes --]

2005-12-05  Steven Munroe  <sjmunroe@us.ibm.com>

	* allocatestack.c (allocate_stack): Handle large page case.
	* tst-stack2.c: Include unistd.h.
	(do_test): Add tests for PTHREAD_STACK_MIN < pagesize and
	user allocated stack of PTHREAD_STACK_MIN bytes.

diff -urN libc24-cvstip-20051128/nptl/allocatestack.c libc24/nptl/allocatestack.c
--- libc24-cvstip-20051128/nptl/allocatestack.c	2005-10-03 19:40:01.000000000 -0500
+++ libc24/nptl/allocatestack.c	2005-12-05 15:56:03.076424936 -0600
@@ -407,11 +407,27 @@
       /* Make sure the size of the stack is enough for the guard and
 	 eventually the thread descriptor.  */
       guardsize = (attr->guardsize + pagesize_m1) & ~pagesize_m1;
-      if (__builtin_expect (size < (guardsize + __static_tls_size
-				    + MINIMAL_REST_STACK + pagesize_m1 + 1),
+      if (__builtin_expect (size < ((guardsize + __static_tls_size
+				    + MINIMAL_REST_STACK
+				    + pagesize_m1) & ~pagesize_m1),
 			    0))
-	/* The stack is too small (or the guard too large).  */
-	return EINVAL;
+	{
+	/* The stack is too small (or the guard too large), but this might not
+	   be an error.  If we are on a system that supports multiple page
+	   sizes,  the current page size may be larger then PTHREAD_STACK_MIN,
+	   but we need to allocate a minimum of two pages for guard and stack.
+	   In this case we can allocate the two page minimum.  */
+	  if ((size >= PTHREAD_STACK_MIN)
+	    && (PTHREAD_STACK_MIN< ((pagesize_m1 + 1)  * 2)))
+	    /* The requested size is >= PTHREAD_STACK_MIN,  so the application
+	       expect this to work. But PTHREAD_STACK_MIN is < 2 of the
+	       current pages,  so bump the stack size up to two pages at the
+	       current page size.  */
+	    size = (pagesize_m1 + 1) * 2;
+	  else
+	    /* Not the large page case so return EINVAL.  */
+	    return EINVAL;
+	}
 
       /* Try to get a stack from the cache.  */
       reqsize = size;
diff -urN libc24-cvstip-20051128/nptl/tst-stack2.c libc24/nptl/tst-stack2.c
--- libc24-cvstip-20051128/nptl/tst-stack2.c	2003-09-03 00:06:52.000000000 -0500
+++ libc24/nptl/tst-stack2.c	2005-12-05 15:45:30.599457656 -0600
@@ -23,6 +23,7 @@
 #include <pthread.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <unistd.h>
 
 static int seen;
 
@@ -38,21 +39,94 @@
 {
   pthread_attr_t attr;
   pthread_attr_init (&attr);
+  long pagesize;
 
   int result = 0;
-  int res = pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+  int res;
+
+  pagesize = sysconf(_SC_PAGESIZE);
+  printf ("sysconf(_SC_PAGESIZE) = %ld\n", pagesize);
+  
+  res = pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
   if (res)
     {
       printf ("pthread_attr_setstacksize failed %d\n", res);
       result = 1;
     }
 
-  /* Create the thread.  */
+  /* Create the thread with PTHREAD_STACK_MIN stack size.  */
   pthread_t th;
   res = pthread_create (&th, &attr, tf, NULL);
   if (res)
     {
       printf ("pthread_create failed %d\n", res);
+      
+      if ((PTHREAD_STACK_MIN) < (2 * pagesize))
+        {
+	/* This should have worked because the system has multiple pages sizes
+	   and it is currently running with pagesize >= PTHREAD_STACK_MIN.  */
+          puts("PTHREAD_STACK_MIN < (2 * pagesize)");
+	}
+      else
+        result = 1;
+    }
+  else
+    {
+      res = pthread_join (th, NULL);
+      if (res)
+	{
+	  printf ("pthread_join failed %d\n", res);
+	  result = 1;
+	}
+    }
+    
+  /* The PTHREAD_STACK_MIN should always be valid when stackaddr is set.  */
+  
+  void *stack;
+  size_t size = PTHREAD_STACK_MIN;
+
+  
+  if (posix_memalign (&stack, getpagesize (), size) != 0)
+    {
+      puts ("out of memory while allocating the stack memory");
+      return (1);
+    }
+
+  if (pthread_attr_init (&attr) != 0)
+    {
+      puts ("attr_init failed");
+      return (1);
+    }
+
+  if (pthread_attr_setstack (&attr, stack, size) != 0)
+    {
+      puts ("attr_setstack failed");
+      return (1);
+    }
+    
+  res = pthread_create (&th, &attr, tf, NULL);
+  if (res)
+    {
+      printf ("pthread_create failed %d\n", res);
+      result = 1;
+    }
+  else
+    {
+      res = pthread_join (th, NULL);
+      if (res)
+	{
+	  printf ("pthread_join failed %d\n", res);
+	  result = 1;
+	}
+    }
+
+  /* The default pthread_attr_t should always work, even if the page
+     size is larger then expected.  */
+    
+  res = pthread_create (&th, NULL, tf, NULL);
+  if (res)
+    {
+      printf ("pthread_create failed %d\n", res);
       result = 1;
     }
   else
@@ -65,9 +139,9 @@
 	}
     }
 
-  if (seen != 1)
+  if (seen != 3)
     {
-      printf ("seen %d != 1\n", seen);
+      printf ("seen %d != 3\n", seen);
       result = 1;
     }
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-12-13  6:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-12-05 22:12 [PATCH] NPTL proposed large page fix for pthread_create Steven Munroe
2005-12-13  6:34 ` Ulrich Drepper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).