about summary refs log tree commit diff
path: root/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog8
-rw-r--r--linuxthreads/manager.c22
-rw-r--r--linuxthreads/pthread.c5
3 files changed, 19 insertions, 16 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 7d161b8254..9bdf83e951 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,11 @@
+1999-12-18  Ulrich Drepper  <drepper@cygnus.com>
+
+	* manager.c (pthread_allocate_stack): Correct computation of
+	new_thread_bottom.  Correct handling of stack size and when the
+	rlimit method to guard for stack growth is used.
+	* pthread.c (pthread_initialize): Stack limit must be STACK_SIZE
+	minus one pagesize (not two).
+
 1999-12-03  Andreas Jaeger  <aj@suse.de>
 
 	* Versions: Add __res_state with version GLIBC_2.2.
diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c
index 307ce63721..0cbb426c9d 100644
--- a/linuxthreads/manager.c
+++ b/linuxthreads/manager.c
@@ -289,9 +289,12 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
     }
   else
     {
+      stacksize = STACK_SIZE - pagesize;
+      if (attr != NULL)
+        stacksize = MIN (stacksize, roundup(attr->__stacksize, pagesize));
       /* Allocate space for stack and thread descriptor at default address */
       new_thread = default_new_thread;
-      new_thread_bottom = (char *) new_thread - STACK_SIZE;
+      new_thread_bottom = (char *) (new_thread + 1) - stacksize;
       if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
                INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
                MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
@@ -300,14 +303,10 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
         return -1;
       /* We manage to get a stack.  Now see whether we need a guard
          and allocate it if necessary.  Notice that the default
-         attributes (stack_size = STACK_SIZE - pagesize and
-         guardsize = pagesize) do not need a guard page, since
-         the RLIMIT_STACK soft limit prevents stacks from
-         running into one another. */
-      if (attr == NULL ||
-          attr->__guardsize == 0 ||
-          (attr->__guardsize == pagesize &&
-           attr->__stacksize == STACK_SIZE - pagesize))
+         attributes (stack_size = STACK_SIZE - pagesize) do not need
+	 a guard page, since the RLIMIT_STACK soft limit prevents stacks
+	 from running into one another. */
+      if (stacksize == STACK_SIZE - pagesize)
         {
           /* We don't need a guard page. */
           guardaddr = NULL;
@@ -316,10 +315,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
       else
         {
           /* Put a bad page at the bottom of the stack */
-          stacksize = roundup(attr->__stacksize, pagesize);
-          if (stacksize >= STACK_SIZE - pagesize)
-            stacksize = STACK_SIZE - pagesize;
-          guardaddr = (void *)new_thread - stacksize;
+          guardaddr = (void *)new_thread_bottom - stacksize;
           guardsize = attr->__guardsize;
           if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
               == MAP_FAILED)
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 41d09a833c..a9083635b6 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -300,10 +300,9 @@ static void pthread_initialize(void)
   __pthread_initial_thread_bos =
     (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
   /* Play with the stack size limit to make sure that no stack ever grows
-     beyond STACK_SIZE minus two pages (one page for the thread descriptor
-     immediately beyond, and one page to act as a guard page). */
+     beyond STACK_SIZE minus one page (to act as a guard page). */
   getrlimit(RLIMIT_STACK, &limit);
-  max_stack = STACK_SIZE - 2 * __getpagesize();
+  max_stack = STACK_SIZE - __getpagesize();
   if (limit.rlim_cur > max_stack) {
     limit.rlim_cur = max_stack;
     setrlimit(RLIMIT_STACK, &limit);