Browse Source

sync some style changes and stack fixes with glibc

Mike Frysinger 18 years ago
parent
commit
c196ed5c18
1 changed files with 88 additions and 12 deletions
  1. 88 12
      libpthread/linuxthreads/manager.c

+ 88 - 12
libpthread/linuxthreads/manager.c

@@ -14,9 +14,12 @@
 
 /* The "thread manager" thread: manages creation and termination of threads */
 
-/* mods for uClibc: getpwd and getpagesize are the syscalls */
+/* mods for uClibc */
 #define __getpid getpid
 #define __getpagesize getpagesize
+#define __sched_get_priority_max sched_get_priority_max
+#define __sched_getscheduler sched_getscheduler
+#define __sched_getparam sched_getparam
 
 #include <features.h>
 #define __USE_GNU
@@ -81,8 +84,13 @@ volatile pthread_descr __pthread_last_event;
 
 static inline pthread_descr thread_segment(int seg)
 {
+# ifdef _STACK_GROWS_UP
+  return (pthread_descr)(THREAD_STACK_START_ADDRESS + (seg - 1) * STACK_SIZE)
+         + 1;
+# else
   return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
          - 1;
+# endif
 }
 
 /* Flag set in signal handler to record child termination */
@@ -149,7 +157,7 @@ __pthread_manager(void *arg)
   sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */
   sigdelset(&manager_mask, SIGTRAP);            /* for debugging purposes */
   if (__pthread_threads_debug && __pthread_sig_debug > 0)
-      sigdelset(&manager_mask, __pthread_sig_debug);
+    sigdelset(&manager_mask, __pthread_sig_debug);
   sigprocmask(SIG_SETMASK, &manager_mask, NULL);
   /* Raise our priority to match that of main thread */
   __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
@@ -245,10 +253,12 @@ __pthread_manager(void *arg)
         PDEBUG("got REQ_DEBUG\n");
 	/* Make gdb aware of new thread and gdb will restart the
 	   new thread when it is ready to handle the new thread. */
-	if (__pthread_threads_debug && __pthread_sig_debug > 0) {
-      PDEBUG("about to call raise(__pthread_sig_debug)\n");
+	if (__pthread_threads_debug && __pthread_sig_debug > 0)
+	{
+	  PDEBUG("about to call raise(__pthread_sig_debug)\n");
 	  raise(__pthread_sig_debug);
 	}
+        break;
       case REQ_KICK:
 	/* This is just a prod to get the manager to reap some
 	   threads right away, avoiding a potential delay at shutdown. */
@@ -279,6 +289,7 @@ int __pthread_manager_event(void *arg)
 }
 
 /* Process creation */
+
 static int
 __attribute__ ((noreturn))
 pthread_start_thread(void *arg)
@@ -286,9 +297,16 @@ pthread_start_thread(void *arg)
   pthread_descr self = (pthread_descr) arg;
   struct pthread_request request;
   void * outcome;
+#if HP_TIMING_AVAIL
+  hp_timing_t tmpclock;
+#endif
   /* Initialize special thread_self processing, if any.  */
 #ifdef INIT_THREAD_SELF
   INIT_THREAD_SELF(self, self->p_nr);
+#endif
+#if HP_TIMING_AVAIL
+  HP_TIMING_NOW (tmpclock);
+  THREAD_SETMEM (self, p_cpuclock_offset, tmpclock);
 #endif
   PDEBUG("\n");
   /* Make sure our pid field is initialized, just in case we get there
@@ -363,12 +381,39 @@ 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. */
+# ifdef USE_TLS
+      /* This value is not needed.  */
+      new_thread = (pthread_descr) attr->__stackaddr;
+      new_thread_bottom = (char *) new_thread;
+# else
+      new_thread = (pthread_descr) attr->__stackaddr;
+      new_thread_bottom = (char *) (new_thread + 1);
+# endif
+      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
+	 of the segment, relying on the associated stacksize to
+	 determine the low end of the segment.  This differs from many
+	 (but not all) other pthreads implementations.  The intent is
+	 that on machines with a single stack growing toward higher
+	 addresses, stackaddr would be the lowest address in the stack
+	 segment, so that it is consistently close to the initial sp
+	 value. */
+# ifdef USE_TLS
+      new_thread = (pthread_descr) attr->__stackaddr;
+# else
       new_thread =
         (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
+# endif
       new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
       guardaddr = NULL;
       guardsize = 0;
+#endif
       __pthread_nonstandard_stacks = 1;
     }
   else
@@ -493,7 +538,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
 
   /* First check whether we have to change the policy and if yes, whether
      we can  do this.  Normally this should be done by examining the
-     return value of the sched_setscheduler call in pthread_start_thread
+     return value of the __sched_setscheduler call in pthread_start_thread
      but this is hard to implement.  FIXME  */
   if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0)
     return EPERM;
@@ -546,8 +591,8 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
 	      sizeof (struct sched_param));
       break;
     case PTHREAD_INHERIT_SCHED:
-      new_thread->p_start_args.schedpolicy = sched_getscheduler(father_pid);
-      sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
+      new_thread->p_start_args.schedpolicy = __sched_getscheduler(father_pid);
+      __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
       break;
     }
     new_thread->p_priority =
@@ -588,17 +633,36 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
 	  __pthread_lock(new_thread->p_lock, NULL);
 
 	  /* We have to report this event.  */
+#ifdef NEED_SEPARATE_REGISTER_STACK
+	  /* Perhaps this version should be used on all platforms. But
+	   this requires that __clone2 be uniformly supported
+	   everywhere.
+
+	   And there is some argument for changing the __clone2
+	   interface to pass sp and bsp instead, making it more IA64
+	   specific, but allowing stacks to grow outward from each
+	   other, to get less paging and fewer mmaps.  */
+	  pid = __clone2(pthread_start_thread_event,
+  		 (void **)new_thread_bottom,
+			 (char *)stack_addr - 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 |
 			__pthread_sig_cancel, new_thread);
-
+#endif
 	  saved_errno = errno;
 	  if (pid != -1)
 	    {
 	      /* Now fill in the information about the new thread in
-	         the newly created thread's data structure.  We cannot let
-	         the new thread do this since we don't know whether it was
-	         already scheduled when we send the event.  */
+		 the newly created thread's data structure.  We cannot let
+		 the new thread do this since we don't know whether it was
+		 already scheduled when we send the event.  */
 	      new_thread->p_eventbuf.eventdata = new_thread;
 	      new_thread->p_eventbuf.eventnum = TD_CREATE;
 	      __pthread_last_event = new_thread;
@@ -619,9 +683,21 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
   if (pid == 0)
     {
       PDEBUG("cloning new_thread = %p\n", new_thread);
+#ifdef NEED_SEPARATE_REGISTER_STACK
+      pid = __clone2(pthread_start_thread,
+		     (void **)new_thread_bottom,
+                     (char *)stack_addr - 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 |
 		    __pthread_sig_cancel, new_thread);
+#endif /* !NEED_SEPARATE_REGISTER_STACK */
       saved_errno = errno;
     }
   /* Check if cloning succeeded */
@@ -922,7 +998,7 @@ void __pthread_manager_adjust_prio(int thread_prio)
 
   if (thread_prio <= __pthread_manager_thread.p_priority) return;
   param.sched_priority =
-    thread_prio < sched_get_priority_max(SCHED_FIFO)
+    thread_prio < __sched_get_priority_max(SCHED_FIFO)
     ? thread_prio + 1 : thread_prio;
   sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
   __pthread_manager_thread.p_priority = thread_prio;