From e48b68570d872ef7ece1d873c0ea298ea76393f3 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 15 Nov 2013 14:57:45 -0800 Subject: [PATCH] Clean up the pthread_create trampoline. Bug: 8206355 Bug: 11693195 Change-Id: I35cc024d5b6ebd19d1d2e45610db185addaf45df --- libc/Android.mk | 1 - libc/bionic/__thread_entry.cpp | 59 ---------------------------------- libc/bionic/pthread_create.cpp | 29 +++++++++++++++-- libc/bionic/pthread_internal.h | 3 -- libc/bionic/pthread_key.cpp | 2 +- 5 files changed, 28 insertions(+), 66 deletions(-) delete mode 100644 libc/bionic/__thread_entry.cpp diff --git a/libc/Android.mk b/libc/Android.mk index b24320dcc..aad6b048e 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -289,7 +289,6 @@ libc_bionic_src_files := \ bionic/sysconf.cpp \ bionic/thread_atexit.cpp \ bionic/tdestroy.cpp \ - bionic/__thread_entry.cpp \ bionic/timer.cpp \ bionic/tmpfile.cpp \ bionic/unlink.cpp \ diff --git a/libc/bionic/__thread_entry.cpp b/libc/bionic/__thread_entry.cpp deleted file mode 100644 index 3505f8b5b..000000000 --- a/libc/bionic/__thread_entry.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "pthread_internal.h" - -#include "private/bionic_tls.h" - -// This trampoline is called from the assembly __bionic_clone function. -int __thread_entry(void* arg) { - pthread_internal_t* thread = reinterpret_cast(arg); - - // Wait for our creating thread to release us. This lets it have time to - // notify gdb about this thread before we start doing anything. - // This also provides the memory barrier needed to ensure that all memory - // accesses previously made by the creating thread are visible to us. - pthread_mutex_t* start_mutex = (pthread_mutex_t*) &thread->tls[TLS_SLOT_START_MUTEX]; - pthread_mutex_lock(start_mutex); - pthread_mutex_destroy(start_mutex); - - __init_tls(thread); - - __init_alternate_signal_stack(thread); - - if ((thread->internal_flags & PTHREAD_INTERNAL_FLAG_THREAD_INIT_FAILED) != 0) { - pthread_exit(NULL); - } - - void* result = thread->start_routine(thread->start_routine_arg); - pthread_exit(result); - - return 0; -} diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 386e8d147..6ed01ff19 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -134,6 +134,31 @@ static void* __create_thread_stack(pthread_internal_t* thread) { return stack; } +static int __pthread_start(void* arg) { + pthread_internal_t* thread = reinterpret_cast(arg); + + // Wait for our creating thread to release us. This lets it have time to + // notify gdb about this thread before we start doing anything. + // This also provides the memory barrier needed to ensure that all memory + // accesses previously made by the creating thread are visible to us. + pthread_mutex_t* start_mutex = (pthread_mutex_t*) &thread->tls[TLS_SLOT_START_MUTEX]; + pthread_mutex_lock(start_mutex); + pthread_mutex_destroy(start_mutex); + + __init_tls(thread); + + __init_alternate_signal_stack(thread); + + if ((thread->internal_flags & PTHREAD_INTERNAL_FLAG_THREAD_INIT_FAILED) != 0) { + pthread_exit(NULL); + } + + void* result = thread->start_routine(thread->start_routine_arg); + pthread_exit(result); + + return 0; +} + int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, void* (*start_routine)(void*), void* arg) { ErrnoRestorer errno_restorer; @@ -198,7 +223,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, thread->start_routine_arg = arg; int flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS; - int tid = __bionic_clone(flags, child_stack, NULL, thread->tls, NULL, __thread_entry, thread); + int tid = __bionic_clone(flags, child_stack, NULL, thread->tls, NULL, __pthread_start, thread); if (tid < 0) { int clone_errno = errno; if ((thread->attr.flags & PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK) == 0) { @@ -213,7 +238,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, int init_errno = _init_thread(thread, true); if (init_errno != 0) { - // Mark the thread detached and let its __thread_entry run to + // Mark the thread detached and let its __pthread_start run to // completion. (It'll just exit immediately, cleaning up its resources.) thread->internal_flags |= PTHREAD_INTERNAL_FLAG_THREAD_INIT_FAILED; thread->attr.flags |= PTHREAD_ATTR_FLAG_DETACHED; diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index 52cfbcecf..d8ad544ef 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -55,9 +55,6 @@ struct pthread_internal_t { char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE]; }; -extern "C" { - __LIBC_HIDDEN__ int __thread_entry(void* arg); // Called from assembler. -} __LIBC_HIDDEN__ int _init_thread(pthread_internal_t* thread, bool add_to_thread_list); __LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread); __LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*); diff --git a/libc/bionic/pthread_key.cpp b/libc/bionic/pthread_key.cpp index 440a715e5..f2f4d20f6 100644 --- a/libc/bionic/pthread_key.cpp +++ b/libc/bionic/pthread_key.cpp @@ -215,7 +215,7 @@ int pthread_key_delete(pthread_key_t key) { // Skip zombie threads. They don't have a valid TLS area any more. // Similarly, it is possible to have t->tls == NULL for threads that // were just recently created through pthread_create() but whose - // startup trampoline (__thread_entry) hasn't been run yet by the + // startup trampoline (__pthread_start) hasn't been run yet by the // scheduler. t->tls will also be NULL after a thread's stack has been // unmapped but before the ongoing pthread_join() is finished. if ((t->attr.flags & PTHREAD_ATTR_FLAG_ZOMBIE) || t->tls == NULL) {