Make pthread join_state not protected by g_thread_list_lock.

1. Move the representation of thread join_state from pthread.attr.flag
   to pthread.join_state. This clarifies thread state change.
2. Use atomic operations for pthread.join_state. So we don't need to
   protect it by g_thread_list_lock. g_thread_list_lock will be reduced
   to only protect g_thread_list or even removed in further changes.

Bug: 19636317
Change-Id: I31fb143a7c69508c7287307dd3b0776993ec0f43
diff --git a/libc/bionic/pthread_join.cpp b/libc/bionic/pthread_join.cpp
index e3350ef..15543b4 100644
--- a/libc/bionic/pthread_join.cpp
+++ b/libc/bionic/pthread_join.cpp
@@ -44,16 +44,15 @@
       return ESRCH;
     }
 
-    if ((thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) != 0) {
+    ThreadJoinState old_state = THREAD_NOT_JOINED;
+    while ((old_state == THREAD_NOT_JOINED || old_state == THREAD_EXITED_NOT_JOINED) &&
+           !atomic_compare_exchange_weak(&thread->join_state, &old_state, THREAD_JOINED)) {
+    }
+
+    if (old_state == THREAD_DETACHED || old_state == THREAD_JOINED) {
       return EINVAL;
     }
 
-    if ((thread->attr.flags & PTHREAD_ATTR_FLAG_JOINED) != 0) {
-      return EINVAL;
-    }
-
-    // Okay, looks like we can signal our intention to join.
-    thread->attr.flags |= PTHREAD_ATTR_FLAG_JOINED;
     tid = thread->tid;
     tid_ptr = &thread->tid;
   }