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_attr.cpp b/libc/bionic/pthread_attr.cpp
index be1c252..7ad3431 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -170,6 +170,11 @@
int pthread_getattr_np(pthread_t t, pthread_attr_t* attr) {
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(t);
*attr = thread->attr;
+ // We prefer reading join_state here to setting thread->attr.flags in pthread_detach.
+ // Because data race exists in the latter case.
+ if (atomic_load(&thread->join_state) == THREAD_DETACHED) {
+ attr->flags |= PTHREAD_ATTR_FLAG_DETACHED;
+ }
// The main thread's stack information is not stored in thread->attr, and we need to
// collect that at runtime.
if (thread->tid == getpid()) {