about summary refs log tree commit diff
path: root/nptl/sysdeps/pthread/createthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/pthread/createthread.c')
-rw-r--r--nptl/sysdeps/pthread/createthread.c75
1 files changed, 20 insertions, 55 deletions
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
index 58a7b637a1..49383cf769 100644
--- a/nptl/sysdeps/pthread/createthread.c
+++ b/nptl/sysdeps/pthread/createthread.c
@@ -51,32 +51,26 @@ int *__libc_multiple_threads_ptr attribute_hidden;
 
 static int
 do_clone (struct pthread *pd, const struct pthread_attr *attr,
-	  int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS)
+	  int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
+	  int stopped)
 {
 #ifdef PREPARE_CREATE
   PREPARE_CREATE;
 #endif
 
-  /* Lame old kernels do not have CLONE_STOPPED support.  For those do
-     not pass the flag, not instead use the futex method.  */
-#ifndef __ASSUME_CLONE_STOPPED
-# define final_clone_flags clone_flags & ~CLONE_STOPPED
-  if (clone_flags & CLONE_STOPPED)
+  if (stopped)
     /* We Make sure the thread does not run far by forcing it to get a
        lock.  We lock it here too so that the new thread cannot continue
        until we tell it to.  */
     lll_lock (pd->lock);
-#else
-# define final_clone_flags clone_flags
-#endif
 
-  if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, final_clone_flags,
+  if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
 		  pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
     /* Failed.  */
     return errno;
 
   /* Now we have the possibility to set scheduling parameters etc.  */
-  if (__builtin_expect ((clone_flags & CLONE_STOPPED) != 0, 0))
+  if (__builtin_expect (stopped != 0, 0))
     {
       INTERNAL_SYSCALL_DECL (err);
       int res = 0;
@@ -97,20 +91,8 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
 	      (void) INTERNAL_SYSCALL (tgkill, err2, 3,
 				       THREAD_GETMEM (THREAD_SELF, pid),
 				       pd->tid, SIGCANCEL);
-
-# ifdef __ASSUME_CLONE_STOPPED
-	      /* Then wake it up so that the signal can be processed.  */
-	      (void) INTERNAL_SYSCALL (tgkill, err2, 3,
-				       THREAD_GETMEM (THREAD_SELF, pid),
-				       pd->tid, SIGCONT);
-# endif
 #else
 	      (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCANCEL);
-
-# ifdef __ASSUME_CLONE_STOPPED
-	      /* Then wake it up so that the signal can be processed.  */
-	      (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCONT);
-# endif
 #endif
 
 	      return INTERNAL_SYSCALL_ERRNO (res, err);
@@ -126,20 +108,6 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
 	  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
 	    goto err_out;
 	}
-
-#ifdef __ASSUME_CLONE_STOPPED
-      /* Now start the thread for real.  */
-# if __ASSUME_TGKILL
-      res = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
-			      pd->tid, SIGCONT);
-# else
-      res = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCONT);
-# endif
-
-      /* If something went wrong, kill the thread.  */
-      if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
-	goto err_out;
-#endif
     }
 
   /* We now have for sure more than one thread.  The main thread might
@@ -198,13 +166,6 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
 #endif
 		     | 0);
 
-  /* If the newly created threads has to be started stopped since we
-     have to set the scheduling parameters or set the affinity we set
-     the CLONE_STOPPED flag.  */
-  if (attr != NULL && (attr->cpuset != NULL
-		       || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
-    clone_flags |= CLONE_STOPPED;
-
   if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
     {
       /* The parent thread is supposed to report events.  Check whether
@@ -217,8 +178,8 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
 	{
 	  /* Create the thread.  We always create the thread stopped
 	     so that it does not get far before we tell the debugger.  */
-	  int res = do_clone (pd, attr, clone_flags | CLONE_STOPPED,
-			      start_thread, STACK_VARIABLES_ARGS);
+	  int res = do_clone (pd, attr, clone_flags, start_thread,
+			      STACK_VARIABLES_ARGS, 1);
 	  if (res == 0)
 	    {
 	      /* Now fill in the information about the new thread in
@@ -247,20 +208,24 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
     }
 
 #ifdef NEED_DL_SYSINFO
-  assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO(pd));
+  assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO (pd));
 #endif
 
+  /* Determine whether the newly created threads has to be started
+     stopped since we have to set the scheduling parameters or set the
+     affinity.  */
+  int stopped = 0;
+  if (attr != NULL && (attr->cpuset != NULL
+		       || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
+    stopped = 1;
+
   /* Actually create the thread.  */
   int res = do_clone (pd, attr, clone_flags, start_thread,
-		      STACK_VARIABLES_ARGS);
+		      STACK_VARIABLES_ARGS, stopped);
 
-#ifndef __ASSUME_CLONE_STOPPED
-  if (res == 0 && (clone_flags & CLONE_STOPPED))
-    {
-      /* And finally restart the new thread.  */
-      lll_unlock (pd->lock);
-    }
-#endif
+  if (res == 0 && stopped)
+    /* And finally restart the new thread.  */
+    lll_unlock (pd->lock);
 
   return res;
 }