about summary refs log tree commit diff
path: root/nptl/sysdeps/pthread/createthread.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-08-03 06:47:02 +0000
committerUlrich Drepper <drepper@redhat.com>2003-08-03 06:47:02 +0000
commitf1205aa71fb0131eb9d1e2efdd5fbcfaa85ad27c (patch)
tree7459ac5d9ff530a22b4035697530a49e49ce3ff7 /nptl/sysdeps/pthread/createthread.c
parent0cbc6c4eba0d6c957917e036a0822c84b92443fc (diff)
downloadglibc-f1205aa71fb0131eb9d1e2efdd5fbcfaa85ad27c.tar.gz
glibc-f1205aa71fb0131eb9d1e2efdd5fbcfaa85ad27c.tar.xz
glibc-f1205aa71fb0131eb9d1e2efdd5fbcfaa85ad27c.zip
Update.
	* sysdeps/pthread/createthread.c (do_clone): If __ASSUME_CLONE_STOPPED
	is not defined, do explicit synchronization.
	(create_thread): Do not lock pd->lock here.  If __ASSUME_CLONE_STOPPED
	is not defined also unlock pd->lock for non-debugging case in case
	it is necessary.
	* pthread_create.c (start_thread): Always get and release pd->lock
	if __ASSUME_CLONE_STOPPED is not defined.
	(start_thread_debug): Removed.  Adjust users.
	* allocatestack.c (allocate_stack): Always initialize lock if
	__ASSUME_CLONE_STOPPED is not defined.
	* Makefile (tests): Add tst-sched1.
	* tst-sched1.c: New file.
Diffstat (limited to 'nptl/sysdeps/pthread/createthread.c')
-rw-r--r--nptl/sysdeps/pthread/createthread.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
index dd5bb5a25b..23012bb476 100644
--- a/nptl/sysdeps/pthread/createthread.c
+++ b/nptl/sysdeps/pthread/createthread.c
@@ -25,6 +25,8 @@
 #include <ldsodefs.h>
 #include <tls.h>
 
+#include "kernel-features.h"
+
 
 #define CLONE_SIGNAL    	(CLONE_SIGHAND | CLONE_THREAD)
 
@@ -55,7 +57,20 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
   PREPARE_CREATE;
 #endif
 
-  if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
+  /* 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)
+    /* 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,
 		  pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
     /* Failed.  */
     return errno;
@@ -86,8 +101,10 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
 	    goto err_out;
 	}
 
+#ifdef __ASSUME_CLONE_STOPPED
       /* Now start the thread for real.  */
       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))
@@ -98,8 +115,10 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
 	err_out:
 	  (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, err, 2, pd->tid, SIGCONT);
+	  (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCONT);
+#endif
 
 	  return INTERNAL_SYSCALL_ERRNO (res, err);
 	}
@@ -175,15 +194,10 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
       if ((_mask & (__nptl_threads_events.event_bits[_idx]
 		    | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
 	{
-	  /* We have to report the new thread.  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);
-
-	  /* Create the thread.  */
-	  int res = do_clone (pd, attr, clone_flags, start_thread_debug,
-			      STACK_VARIABLES_ARGS);
+	  /* 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);
 	  if (res == 0)
 	    {
 	      /* Now fill in the information about the new thread in
@@ -216,5 +230,16 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
 #endif
 
   /* Actually create the thread.  */
-  return do_clone (pd, attr, clone_flags, start_thread, STACK_VARIABLES_ARGS);
+  int res = do_clone (pd, attr, clone_flags, start_thread,
+		      STACK_VARIABLES_ARGS);
+
+#ifndef __ASSUME_CLONE_STOPPED
+  if (res == 0 && (clone_flags & CLONE_STOPPED))
+    {
+      /* And finally restart the new thread.  */
+      lll_unlock (pd->lock);
+    }
+#endif
+
+  return res;
 }