OSDN Git Service

Use bionic lock in pthread_internal_t.
authorYabin Cui <yabinc@google.com>
Fri, 23 Oct 2015 03:07:56 +0000 (20:07 -0700)
committerYabin Cui <yabinc@google.com>
Fri, 23 Oct 2015 03:14:33 +0000 (20:14 -0700)
It removes calling to pthread_mutex_lock() at the beginning of new
thread, which helps to support thread sanitizer.

Change-Id: Ia3601c476de7976a9177b792bd74bb200cee0e13

libc/bionic/pthread_create.cpp
libc/bionic/pthread_internal.h
libc/private/bionic_lock.h

index e260e97..ce43009 100644 (file)
@@ -193,8 +193,7 @@ static int __pthread_start(void* arg) {
   // 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_lock(&thread->startup_handshake_mutex);
-  pthread_mutex_destroy(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.lock();
 
   __init_alternate_signal_stack(thread);
 
@@ -233,14 +232,14 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
     return result;
   }
 
-  // Create a mutex for the thread in TLS to wait on once it starts so we can keep
+  // Create a lock for the thread to wait on once it starts so we can keep
   // it from doing anything until after we notify the debugger about it
   //
   // This also provides the memory barrier we need to ensure that all
   // memory accesses previously performed by this thread are visible to
   // the new thread.
-  pthread_mutex_init(&thread->startup_handshake_mutex, NULL);
-  pthread_mutex_lock(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.init(false);
+  thread->startup_handshake_lock.lock();
 
   thread->start_routine = start_routine;
   thread->start_routine_arg = arg;
@@ -263,7 +262,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
     // We don't have to unlock the mutex at all because clone(2) failed so there's no child waiting to
     // be unblocked, but we're about to unmap the memory the mutex is stored in, so this serves as a
     // reminder that you can't rewrite this function to use a ScopedPthreadMutexLocker.
-    pthread_mutex_unlock(&thread->startup_handshake_mutex);
+    thread->startup_handshake_lock.unlock();
     if (thread->mmap_size != 0) {
       munmap(thread->attr.stack_base, thread->mmap_size);
     }
@@ -278,13 +277,13 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
     atomic_store(&thread->join_state, THREAD_DETACHED);
     __pthread_internal_add(thread);
     thread->start_routine = __do_nothing;
-    pthread_mutex_unlock(&thread->startup_handshake_mutex);
+    thread->startup_handshake_lock.unlock();
     return init_errno;
   }
 
   // Publish the pthread_t and unlock the mutex to let the new thread start running.
   *thread_out = __pthread_internal_add(thread);
-  pthread_mutex_unlock(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.unlock();
 
   return 0;
 }
index 6a39a21..d5d62a7 100644 (file)
@@ -31,6 +31,7 @@
 #include <pthread.h>
 #include <stdatomic.h>
 
+#include "private/bionic_lock.h"
 #include "private/bionic_tls.h"
 
 /* Has the thread been detached by a pthread_join or pthread_detach call? */
@@ -89,7 +90,7 @@ struct pthread_internal_t {
 
   void* alternate_signal_stack;
 
-  pthread_mutex_t startup_handshake_mutex;
+  Lock startup_handshake_lock;
 
   size_t mmap_size;
 
index 6a0fd06..a36d1ed 100644 (file)
@@ -31,6 +31,8 @@
 #include <stdatomic.h>
 #include "private/bionic_futex.h"
 
+// Lock is used in places like pthread_rwlock_t, which can be initialized without calling
+// an initialization function. So make sure Lock can be initialized by setting its memory to 0.
 class Lock {
  private:
   enum LockState {
@@ -42,10 +44,6 @@ class Lock {
   bool process_shared;
 
  public:
-  Lock(bool process_shared = false) {
-    init(process_shared);
-  }
-
   void init(bool process_shared) {
     atomic_init(&state, Unlocked);
     this->process_shared = process_shared;