diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-08-03 06:47:02 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-08-03 06:47:02 +0000 |
commit | f1205aa71fb0131eb9d1e2efdd5fbcfaa85ad27c (patch) | |
tree | 7459ac5d9ff530a22b4035697530a49e49ce3ff7 /nptl/sysdeps/pthread/createthread.c | |
parent | 0cbc6c4eba0d6c957917e036a0822c84b92443fc (diff) | |
download | glibc-f1205aa71fb0131eb9d1e2efdd5fbcfaa85ad27c.tar.gz |
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.c | 49 |
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; } |