]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Make _STACK_GROWS_UP work.
authorUlrich Drepper <drepper@redhat.com>
Sat, 16 Jun 2001 18:47:49 +0000 (18:47 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 16 Jun 2001 18:47:49 +0000 (18:47 +0000)
linuxthreads/attr.c
linuxthreads/internals.h
linuxthreads/manager.c
linuxthreads/pthread.c

index 2d06025ba42b605b3a57c069fa9146570b0739fc..eba93f1f6702fadc0008abf3908a349b29988de3 100644 (file)
@@ -283,8 +283,12 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
 
   attr->__inheritsched = descr->p_inheritsched;
   attr->__scope = PTHREAD_SCOPE_SYSTEM;
+#ifdef _STACK_GROWS_DOWN
   attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr
                      - descr->p_guardsize;
+#else
+  attr->__stacksize = (char *)descr->p_guardaddr - (char *)descr;
+#endif
   attr->__guardsize = descr->p_guardsize;
   attr->__stackaddr_set = descr->p_userstack;
 #ifdef NEED_SEPARATE_REGISTER_STACK
@@ -298,7 +302,7 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
 #ifndef _STACK_GROWS_UP
   attr->__stackaddr = (char *)(descr + 1);
 #else
-# error __stackaddr not handled
+  attr->__stackaddr = (char *)descr;
 #endif
 
   return 0;
index aeb45aae01d618642db1f964776744e525d9a35d..a78f9b671b34c051e880116a75a42a889b6055e8 100644 (file)
@@ -384,7 +384,11 @@ static inline pthread_descr thread_self (void)
   else if (__pthread_nonstandard_stacks)
     return __pthread_find_self();
   else
+#ifdef _STACK_GROWS_DOWN
     return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
+#else
+    return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1));
+#endif
 #endif
 }
 
index d436b08f16af3e093c97bba224bf8368bed6cfff..38596ce957734e1dbd0bdaa147ada015da10d68f 100644 (file)
@@ -32,6 +32,7 @@
 #include "spinlock.h"
 #include "restart.h"
 #include "semaphore.h"
+#include <stackinfo.h>
 
 /* Array of active threads. Entry 0 is reserved for the initial thread. */
 struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX] =
@@ -313,6 +314,13 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
 
   if (attr != NULL && attr->__stackaddr_set)
     {
+#ifdef _STACK_GROWS_UP
+      /* The user provided a stack. */
+      new_thread = (pthread_descr) attr->__stackaddr;
+      new_thread_bottom = (char *) (new_thread + 1);
+      guardaddr = attr->__stackaddr + attr->__stacksize;
+      guardsize = 0;
+#else
       /* The user provided a stack.  For now we interpret the supplied
         address as 1 + the highest addr. in the stack segment.  If a
         separate register stack is needed, we place it at the low end
@@ -328,6 +336,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
       new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
       guardaddr = new_thread_bottom;
       guardsize = 0;
+#endif
 #ifndef THREAD_SELF
       __pthread_nonstandard_stacks = 1;
 #endif
@@ -423,12 +432,23 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
         /* No more memory available.  */
         return -1;
 
+#  ifdef _STACK_GROWS_DOWN
       guardaddr = map_addr;
       if (guardsize > 0)
        mprotect (guardaddr, guardsize, PROT_NONE);
 
       new_thread_bottom = (char *) map_addr + guardsize;
       new_thread = ((pthread_descr) (new_thread_bottom + stacksize)) - 1;
+#  elif _STACK_GROWS_UP
+      guardaddr = map_addr + stacksize;
+      if (guardsize > 0)
+       mprotect (guardaddr, guardsize, PROT_NONE);
+
+      new_thread = (pthread_descr) map_addr;
+      new_thread_bottom = (char *) (new_thread + 1);
+#  else
+#    error You must define a stack direction
+#  endif /* Stack direction */
 # else /* !FLOATING_STACKS */
       void *res_addr;
 
@@ -445,6 +465,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
          stacksize = STACK_SIZE - granularity;
        }
 
+#  ifdef _STACK_GROWS_DOWN
       new_thread = default_new_thread;
       new_thread_bottom = (char *) (new_thread + 1) - stacksize;
       map_addr = new_thread_bottom - guardsize;
@@ -464,6 +485,23 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
       guardaddr = map_addr;
       if (guardsize > 0)
        mprotect (guardaddr, guardsize, PROT_NONE);
+#  else
+      /* The thread description goes at the bottom of this area, and
+       * the stack starts directly above it.
+       */
+      new_thread = (pthread_descr)((unsigned long)default_new_thread &~ (STACK_SIZE - 1));
+      map_addr = mmap(new_thread, stacksize + guardsize,
+                     PROT_READ | PROT_WRITE | PROT_EXEC,
+                     MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+      if (map_addr == MAP_FAILED)
+         return -1;
+
+      new_thread_bottom = map_addr + sizeof(*new_thread);
+      guardaddr = map_addr + stacksize;
+      if (guardsize > 0)
+         mprotect (guardaddr, guardsize, PROT_NONE);
+
+#  endif /* stack direction */
 # endif
 #endif /* !NEED_SEPARATE_REGISTER_STACK */
     }
@@ -591,6 +629,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
                         (char *)new_thread - new_thread_bottom,
                         CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
                         __pthread_sig_cancel, new_thread);
+#elif _STACK_GROWS_UP
+         pid = __clone(pthread_start_thread_event, (void **) new_thread_bottom,
+                       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+                       __pthread_sig_cancel, new_thread);
 #else
          pid = __clone(pthread_start_thread_event, (void **) new_thread,
                        CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
@@ -627,6 +669,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
                      (char *)new_thread - new_thread_bottom,
                     CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
                     __pthread_sig_cancel, new_thread);
+#elif _STACK_GROWS_UP
+      pid = __clone(pthread_start_thread, (void **) new_thread_bottom,
+                   CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
+                   __pthread_sig_cancel, new_thread);
 #else
       pid = __clone(pthread_start_thread, (void **) new_thread,
                    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
@@ -643,6 +689,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
                            - new_thread_bottom);
        munmap((caddr_t)new_thread_bottom,
               2 * stacksize + new_thread->p_guardsize);
+#elif _STACK_GROWS_UP
+       size_t stacksize = guardaddr - (char *)new_thread;
+       munmap(new_thread, stacksize + guardsize);
 #else
        size_t stacksize = (char *)(new_thread+1) - new_thread_bottom;
        munmap(new_thread_bottom - guardsize, guardsize + stacksize);
@@ -708,6 +757,10 @@ static void pthread_free(pthread_descr th)
       size_t guardsize = th->p_guardsize;
       /* Free the stack and thread descriptor area */
       char *guardaddr = th->p_guardaddr;
+#ifdef _STACK_GROWS_UP
+      size_t stacksize = guardaddr - (char *)th;
+      guardaddr = (char *)th;
+#else
       /* Guardaddr is always set, even if guardsize is 0.  This allows
         us to compute everything else.  */
       size_t stacksize = (char *)(th+1) - guardaddr - guardsize;
@@ -715,6 +768,7 @@ static void pthread_free(pthread_descr th)
       /* Take account of the register stack, which is below guardaddr.  */
       guardaddr -= stacksize;
       stacksize *= 2;
+#endif
 #endif
       /* Unmap the stack.  */
       munmap(guardaddr, stacksize + guardsize);
index ea35c724d963b441acc14dd06584ac30989dabc8..643e52fea6008da7d940684149f8bc3a7445b83e 100644 (file)
@@ -30,6 +30,7 @@
 #include "internals.h"
 #include "spinlock.h"
 #include "restart.h"
+#include <stackinfo.h>
 
 /* We need the global/static resolver state here.  */
 #include <resolv.h>
@@ -412,11 +413,17 @@ static void pthread_initialize(void)
   /* Test if compare-and-swap is available */
   __pthread_has_cas = compare_and_swap_is_available();
 #endif
+#ifdef _STACK_GROWS_UP
+  /* The initial thread already has all the stack it needs */
+  __pthread_initial_thread_bos = (char *)
+    ((long)CURRENT_STACK_FRAME &~ (STACK_SIZE - 1));
+#else
   /* For the initial stack, reserve at least STACK_SIZE bytes of stack
      below the current stack address, and align that on a
      STACK_SIZE boundary. */
   __pthread_initial_thread_bos =
     (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
+#endif
   /* Update the descriptor for the initial thread. */
   __pthread_initial_thread.p_pid = __getpid();
   /* Likewise for the resolver state _res.  */
@@ -544,6 +551,11 @@ int __pthread_initialize_manager(void)
                         THREAD_MANAGER_STACK_SIZE,
                         CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                         (void *)(long)manager_pipe[0]);
+#elif _STACK_GROWS_UP
+         pid = __clone(__pthread_manager_event,
+                       (void **) __pthread_manager_thread_bos,
+                       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
+                       (void *)(long)manager_pipe[0]);
 #else
          pid = __clone(__pthread_manager_event,
                        (void **) __pthread_manager_thread_tos,
@@ -580,6 +592,10 @@ int __pthread_initialize_manager(void)
                     THREAD_MANAGER_STACK_SIZE,
                     CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                     (void *)(long)manager_pipe[0]);
+#elif _STACK_GROWS_UP
+      pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
+                   CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
+                   (void *)(long)manager_pipe[0]);
 #else
       pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
                    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,