This is the mail archive of the libc-hacker@sourceware.org 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] |
| Other format: | [Raw text] | |
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.
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;
}
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |