diff options
author | Elliott Hughes <enh@google.com> | 2013-11-19 13:31:58 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2013-11-19 14:08:54 -0800 |
commit | 36d6188f8cd8b948fb797f11d9620d63d0c2215a (patch) | |
tree | 86b3162cac031151b2ae44b4d554fce4f9456147 /libc/bionic | |
parent | 318e86ed887e04e593f3db9b84b402d5501ced9b (diff) | |
download | bionic-36d6188f8cd8b948fb797f11d9620d63d0c2215a.tar.gz |
Clean up forking and cloning.
The kernel now maintains the pthread_internal_t::tid field for us,
and __clone was only used in one place so let's inline it so we don't
have to leave such a dangerous function lying around. Also rename
files to match their content and remove some useless #includes.
Change-Id: I24299fb4a940e394de75f864ee36fdabbd9438f9
Diffstat (limited to 'libc/bionic')
-rw-r--r-- | libc/bionic/clone.cpp (renamed from libc/bionic/bionic_clone.c) | 46 | ||||
-rw-r--r-- | libc/bionic/fork.cpp | 22 | ||||
-rw-r--r-- | libc/bionic/pthread_cond.cpp | 1 | ||||
-rw-r--r-- | libc/bionic/pthread_internal.h | 1 | ||||
-rw-r--r-- | libc/bionic/pthread_internals.cpp | 8 | ||||
-rw-r--r-- | libc/bionic/pthread_mutex.cpp | 1 |
6 files changed, 32 insertions, 47 deletions
diff --git a/libc/bionic/bionic_clone.c b/libc/bionic/clone.cpp index 518d99634..1d997fed7 100644 --- a/libc/bionic/bionic_clone.c +++ b/libc/bionic/clone.cpp @@ -25,41 +25,39 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #define __GNU_SOURCE 1 #include <sched.h> #include <stdlib.h> #include <stdarg.h> -#include <stdio.h> -extern pid_t __bionic_clone(uint32_t flags, void* child_stack, int* parent_tid, void* tls, int* child_tid, int (*fn)(void*), void* arg); -extern void __exit(int status); +extern "C" pid_t __bionic_clone(uint32_t flags, void* child_stack, int* parent_tid, void* tls, int* child_tid, int (*fn)(void*), void* arg); +extern "C" void __exit(int status); -/* this function is called from the __bionic_clone - * assembly fragment to call the thread function - * then exit. */ -extern void __bionic_clone_entry(int (*fn)(void*), void* arg) { +// Called from the __bionic_clone assembler to call the thread function then exit. +extern "C" void __bionic_clone_entry(int (*fn)(void*), void* arg) { int status = (*fn)(arg); __exit(status); } int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...) { - va_list args; - int *parent_tidptr = NULL; - void *new_tls = NULL; - int *child_tidptr = NULL; + int* parent_tid = NULL; + void* new_tls = NULL; + int* child_tid = NULL; - /* extract optional parameters - they are cumulative. */ - va_start(args, arg); - if (flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID)) { - parent_tidptr = va_arg(args, int*); - } - if (flags & (CLONE_SETTLS|CLONE_CHILD_SETTID)) { - new_tls = va_arg(args, void*); - } - if (flags & CLONE_CHILD_SETTID) { - child_tidptr = va_arg(args, int*); - } - va_end(args); + // Extract any optional parameters required by the flags. + va_list args; + va_start(args, arg); + if ((flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) { + parent_tid = va_arg(args, int*); + } + if ((flags & (CLONE_SETTLS|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) { + new_tls = va_arg(args, void*); + } + if ((flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) { + child_tid = va_arg(args, int*); + } + va_end(args); - return __bionic_clone(flags, child_stack, parent_tidptr, new_tls, child_tidptr, fn, arg); + return __bionic_clone(flags, child_stack, parent_tid, new_tls, child_tid, fn, arg); } diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp index f7d1c11c3..9fa5fcf5f 100644 --- a/libc/bionic/fork.cpp +++ b/libc/bionic/fork.cpp @@ -27,11 +27,10 @@ */ #include <unistd.h> -#include "pthread_internal.h" - -#include "private/bionic_pthread.h" +#include <sys/syscall.h> -extern "C" int __clone(int, void*, int*, void*, int*); +#include "private/libc_logging.h" +#include "pthread_internal.h" int fork() { // POSIX mandates that the timers of a fork child process be @@ -42,18 +41,17 @@ int fork() { __bionic_atfork_run_prepare(); pthread_internal_t* self = __get_thread(); -#if defined(__x86_64__) - int result = __clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, NULL, NULL, &(self->tid), NULL); + int flags = CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD; +#if defined(__x86_64__) // sys_clone's last two arguments are flipped on x86-64. + int result = syscall(__NR_clone, flags, NULL, NULL, &(self->tid), NULL); #else - int result = __clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, NULL, NULL, NULL, &(self->tid)); + int result = syscall(__NR_clone, flags, NULL, NULL, NULL, &(self->tid)); #endif - if (result != 0) { // Not a child process. + if (result == 0) { + __bionic_atfork_run_child(); + } else { __timer_table_start_stop(0); __bionic_atfork_run_parent(); - } else { - // Fix the tid in the pthread_internal_t struct after a fork. - __pthread_settid(pthread_self(), gettid()); - __bionic_atfork_run_child(); } return result; } diff --git a/libc/bionic/pthread_cond.cpp b/libc/bionic/pthread_cond.cpp index abd453e8f..7c229b5ec 100644 --- a/libc/bionic/pthread_cond.cpp +++ b/libc/bionic/pthread_cond.cpp @@ -38,7 +38,6 @@ #include "private/bionic_atomic_inline.h" #include "private/bionic_futex.h" -#include "private/bionic_pthread.h" #include "private/bionic_time_conversions.h" #include "private/bionic_tls.h" #include "private/thread_private.h" diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index de1ef26b9..bcd9b7104 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -97,6 +97,5 @@ __LIBC_HIDDEN__ extern void __timer_table_start_stop(int); __LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare(); __LIBC_HIDDEN__ extern void __bionic_atfork_run_child(); __LIBC_HIDDEN__ extern void __bionic_atfork_run_parent(); -__LIBC_HIDDEN__ extern int __pthread_settid(pthread_t, pid_t); #endif /* _PTHREAD_INTERNAL_H_ */ diff --git a/libc/bionic/pthread_internals.cpp b/libc/bionic/pthread_internals.cpp index 4b1f6efb9..f8afeaf47 100644 --- a/libc/bionic/pthread_internals.cpp +++ b/libc/bionic/pthread_internals.cpp @@ -73,14 +73,6 @@ pid_t __pthread_gettid(pthread_t t) { return reinterpret_cast<pthread_internal_t*>(t)->tid; } -int __pthread_settid(pthread_t t, pid_t tid) { - if (t == 0) { - return EINVAL; - } - reinterpret_cast<pthread_internal_t*>(t)->tid = tid; - return 0; -} - // Initialize 'ts' with the difference between 'abstime' and the current time // according to 'clock'. Returns -1 if abstime already expired, or 0 otherwise. int __timespec_to_absolute(timespec* ts, const timespec* abstime, clockid_t clock) { diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp index 7e43cd841..1010f11d4 100644 --- a/libc/bionic/pthread_mutex.cpp +++ b/libc/bionic/pthread_mutex.cpp @@ -38,7 +38,6 @@ #include "private/bionic_atomic_inline.h" #include "private/bionic_futex.h" -#include "private/bionic_pthread.h" #include "private/bionic_tls.h" #include "private/thread_private.h" |